From 44925e4be63fdefbdf14183b24276d6531f1cf07 Mon Sep 17 00:00:00 2001 From: Ezequiel Date: Mon, 3 Aug 2026 17:17:29 -0300 Subject: [PATCH] feat: add mango_layouts plugin (#192) * feat: add mango_layouts plugin * fix: address CI validation errors * refactor: inline apply_layout script for cross-device portability * fix: commit inlined script changes in panel.luau * fix: address official PR review feedback * fix: revert noctalia.translate which caused runtime crash * fix: remove setGlyph empty string to prevent fallback skull icon * feat: restore translations using correct noctalia.tr API * refactor: remove unused label fields from layouts table --- mango_layouts/README.md | 56 ++++++++++ mango_layouts/panel.luau | 174 +++++++++++++++++++++++++++++ mango_layouts/plugin.toml | 134 ++++++++++++++++++++++ mango_layouts/thumbnail.webp | Bin 0 -> 38154 bytes mango_layouts/translations/en.json | 35 ++++++ mango_layouts/widget.luau | 68 +++++++++++ 6 files changed, 467 insertions(+) create mode 100644 mango_layouts/README.md create mode 100644 mango_layouts/panel.luau create mode 100644 mango_layouts/plugin.toml create mode 100644 mango_layouts/thumbnail.webp create mode 100644 mango_layouts/translations/en.json create mode 100644 mango_layouts/widget.luau diff --git a/mango_layouts/README.md b/mango_layouts/README.md new file mode 100644 index 0000000..cd7e562 --- /dev/null +++ b/mango_layouts/README.md @@ -0,0 +1,56 @@ +# Mango Layouts + +A clean, minimalist layout switcher plugin for MangoWC. It provides a bar widget and a fast popup panel to switch workspace layouts on the fly, directly from your desktop. + +## Plugin + +| Field | Value | +| --- | --- | +| ID | `ezequiel/mango_layouts` | +| Entries | Bar widget: `btn`; panel: `panel` | + +## Requirements + +Install `jq` and `mmsg` (MangoWC CLI) on `PATH`. +Requires MangoWC as the compositor. + +## Usage + +Add the widget to your Noctalia bar in Settings. Click the widget to open the layout switcher panel and change the current workspace layout. + +Alternatively, toggle the panel directly via command line or keybinding: + +```sh +noctalia msg panel-toggle ezequiel/mango_layouts:panel +``` + +## Settings + +| Setting | Type | Default | Description | +| --- | --- | --- | --- | +| `list_mode` | `bool` | `false` | Display layouts in a vertical list instead of a grid. | +| `show_tile` | `bool` | `true` | Show Tile layout. | +| `show_scroller` | `bool` | `true` | Show Scroller layout. | +| `show_monocle` | `bool` | `true` | Show Monocle layout. | +| `show_grid` | `bool` | `true` | Show Grid layout. | +| `show_fair` | `bool` | `true` | Show Fair layout. | +| `show_deck` | `bool` | `true` | Show Deck layout. | +| `show_dwindle` | `bool` | `true` | Show Dwindle layout. | +| `show_center_tile` | `bool` | `true` | Show Center Tile layout. | +| `show_vertical_tile` | `bool` | `true` | Show Vertical Tile layout. | +| `show_right_tile` | `bool` | `true` | Show Right Tile layout. | +| `show_vertical_scroller` | `bool` | `true` | Show Vertical Scroller layout. | +| `show_vertical_grid` | `bool` | `true` | Show Vertical Grid layout. | +| `show_vertical_deck` | `bool` | `true` | Show Vertical Deck layout. | +| `show_vertical_fair` | `bool` | `true` | Show Vertical Fair layout. | + +Widget Specific Settings: +| Setting | Type | Default | Description | +| --- | --- | --- | --- | +| `show_glyph` | `bool` | `true` | Show the widget icon. | +| `show_text` | `bool` | `false` | Show the active layout name as text. | +| `custom_color` | `string` | `""` | Custom icon/text color (e.g. primary, on_surface). | + +## Notes + +The plugin uses `mmsg` to communicate with MangoWC for reading the active monitor state and applying the selected layout. Make sure you don't use this plugin on compositors other than MangoWC. diff --git a/mango_layouts/panel.luau b/mango_layouts/panel.luau new file mode 100644 index 0000000..073beb5 --- /dev/null +++ b/mango_layouts/panel.luau @@ -0,0 +1,174 @@ +local layouts = { + { sym = "T", name = "tile", glyph = "layout-sidebar" }, + { sym = "S", name = "scroller", glyph = "carousel-horizontal" }, + { sym = "M", name = "monocle", glyph = "square" }, + { sym = "G", name = "grid", glyph = "layout-grid" }, + { sym = "F", name = "fair", glyph = "layout-board-split" }, + { sym = "D", name = "deck", glyph = "layers-difference" }, + { sym = "DW", name = "dwindle", glyph = "layout-2" }, + { sym = "CT", name = "center_tile", glyph = "layout-distribute-vertical" }, + { sym = "VT", name = "vertical_tile", glyph = "layout-rows" }, + { sym = "RT", name = "right_tile", glyph = "layout-sidebar-right" }, + { sym = "VS", name = "vertical_scroller",glyph = "carousel-vertical" }, + { sym = "VG", name = "vertical_grid", glyph = "grid-dots" }, + { sym = "VD", name = "vertical_deck", glyph = "chart-funnel" }, + { sym = "VF", name = "vertical_fair", glyph = "layout-board" }, +} + +local COLUMNS = 4 +local COLUMN_GAP = 2 +local selectedLayout = "" +local pickSlots = {} + +local render + +local function onPickAt(index) + local slot = pickSlots[index] + if slot == nil then return end + selectedLayout = slot.sym + noctalia.runAsync("mmsg dispatch setlayout," .. slot.entry.name) + panel.close() +end + +local function makeGrid(children) + local rows = {} + local row = {} + for i, child in ipairs(children) do + table.insert(row, child) + if #row >= COLUMNS or i == #children then + while #row < COLUMNS do + table.insert(row, ui.spacer({ flexGrow = 1 })) + end + table.insert(rows, ui.row({ gap = COLUMN_GAP, align = "stretch" }, row)) + row = {} + end + end + return ui.column({ gap = COLUMN_GAP }, rows) +end + +local function getShowConfig(name) + if name == "tile" then return noctalia.getConfig("show_tile") end + if name == "scroller" then return noctalia.getConfig("show_scroller") end + if name == "monocle" then return noctalia.getConfig("show_monocle") end + if name == "grid" then return noctalia.getConfig("show_grid") end + if name == "fair" then return noctalia.getConfig("show_fair") end + if name == "deck" then return noctalia.getConfig("show_deck") end + if name == "dwindle" then return noctalia.getConfig("show_dwindle") end + if name == "center_tile" then return noctalia.getConfig("show_center_tile") end + if name == "vertical_tile" then return noctalia.getConfig("show_vertical_tile") end + if name == "right_tile" then return noctalia.getConfig("show_right_tile") end + if name == "vertical_scroller" then return noctalia.getConfig("show_vertical_scroller") end + if name == "vertical_grid" then return noctalia.getConfig("show_vertical_grid") end + if name == "vertical_deck" then return noctalia.getConfig("show_vertical_deck") end + if name == "vertical_fair" then return noctalia.getConfig("show_vertical_fair") end + return true +end + +local function renderButtons(is_list_mode) + local buttons = {} + local i = 0 + for _, entry in ipairs(layouts) do + local raw_val = getShowConfig(entry.name) + local enabled = (raw_val == true) or (raw_val == "true") or (raw_val == nil) + + if enabled then + local slotIndex = i + local isSelected = selectedLayout == entry.sym + pickSlots[slotIndex] = { sym = entry.sym, entry = entry } + + if is_list_mode then + table.insert(buttons, ui.button({ + key = entry.sym, + glyph = entry.glyph, + text = noctalia.tr("name_" .. entry.name), + variant = if isSelected then "primary" else "ghost", + onClick = `onPick{slotIndex}`, + -- If noctalia supports button alignment, this will align it to the left: + -- (If not, it will just remain centered like an elegant menu) + })) + else + -- Grid Mode + table.insert(buttons, ui.column({ + key = entry.sym, + gap = 2, + align = "center", + flexGrow = 1, + }, { + ui.button({ + glyph = entry.glyph, + glyphSize = 18, + variant = if isSelected then "primary" else "ghost", + onClick = `onPick{slotIndex}`, + }), + ui.label({ + text = noctalia.tr("name_" .. entry.name), + fontSize = 9, + fontWeight = "bold", + color = if isSelected then "primary" else "on_surface_variant", + textAlign = "center", + maxLines = 1, + }), + })) + end + i += 1 + end + end + return buttons +end + +render = function() + pickSlots = {} + + local list_mode_raw = noctalia.getConfig("list_mode") + local is_list_mode = (list_mode_raw == true) or (list_mode_raw == "true") + + local content + if is_list_mode then + content = ui.column({ padding = 8, gap = 4 }, renderButtons(true)) + else + content = ui.column({ padding = 12, gap = COLUMN_GAP }, { + makeGrid(renderButtons(false)) + }) + end + + panel.render(ui.column({ flexGrow = 1 }, { + ui.scroll({ flexGrow = 1 }, { + content + }) + })) +end + +function onOpen(context) + selectedLayout = "" + render() + noctalia.runAsync( + "mmsg get all-monitors | jq -r '.monitors[] | select(.active == true and .last_open_surface != null) | .layout_symbol'", + function(result) + if result == nil or result.exitCode ~= 0 then return end + local sym = result.stdout:gsub("%s+", "") + + -- Check if sym exists in our ordered list + local exists = false + for _, l in ipairs(layouts) do + if l.sym == sym then exists = true end + end + selectedLayout = if exists then sym else "" + render() + end + ) +end + +function onPick0() onPickAt(0) end +function onPick1() onPickAt(1) end +function onPick2() onPickAt(2) end +function onPick3() onPickAt(3) end +function onPick4() onPickAt(4) end +function onPick5() onPickAt(5) end +function onPick6() onPickAt(6) end +function onPick7() onPickAt(7) end +function onPick8() onPickAt(8) end +function onPick9() onPickAt(9) end +function onPick10() onPickAt(10) end +function onPick11() onPickAt(11) end +function onPick12() onPickAt(12) end +function onPick13() onPickAt(13) end diff --git a/mango_layouts/plugin.toml b/mango_layouts/plugin.toml new file mode 100644 index 0000000..abef2da --- /dev/null +++ b/mango_layouts/plugin.toml @@ -0,0 +1,134 @@ +id = "ezequiel/mango_layouts" +name = "Mango Layouts" +version = "1.0.0" +plugin_api = 14 +author = "ezequiel" +license = "MIT" +icon = "layout-filled" +description = "Layout switcher for MangoWC" +tags = ["bar", "panel", "mangowc", "utility"] +dependencies = ["jq", "mmsg"] + +[[widget]] +id = "btn" +entry = "widget.luau" +actions = {} + +# -- WIDGET SETTINGS -- +[[widget.setting]] +key = "show_glyph" +type = "bool" +label_key = "show_icon_label" +default = true + +[[widget.setting]] +key = "show_text" +type = "bool" +label_key = "show_text_label" +default = false + +[[widget.setting]] +key = "custom_color" +type = "string" +label_key = "custom_color_label" +description_key = "custom_color_desc" +default = "" + +[[panel]] +id = "panel" +entry = "panel.luau" +width = 240 +height = 250 +placement = "floating" +position = "bottom_right" + +# -- GLOBAL SETTINGS -- +[[setting]] +key = "list_mode" +type = "bool" +label_key = "list_mode_label" +default = false + +[[setting]] +key = "show_tile" +type = "bool" +label_key = "layout_tile_label" +default = true + +[[setting]] +key = "show_scroller" +type = "bool" +label_key = "layout_scroller_label" +default = true + +[[setting]] +key = "show_monocle" +type = "bool" +label_key = "layout_monocle_label" +default = true + +[[setting]] +key = "show_grid" +type = "bool" +label_key = "layout_grid_label" +default = true + +[[setting]] +key = "show_fair" +type = "bool" +label_key = "layout_fair_label" +default = true + +[[setting]] +key = "show_deck" +type = "bool" +label_key = "layout_deck_label" +default = true + +[[setting]] +key = "show_dwindle" +type = "bool" +label_key = "layout_dwindle_label" +default = true + +[[setting]] +key = "show_center_tile" +type = "bool" +label_key = "layout_center_tile_label" +default = true + +[[setting]] +key = "show_vertical_tile" +type = "bool" +label_key = "layout_vertical_tile_label" +default = true + +[[setting]] +key = "show_right_tile" +type = "bool" +label_key = "layout_right_tile_label" +default = true + +[[setting]] +key = "show_vertical_scroller" +type = "bool" +label_key = "layout_vertical_scroller_label" +default = true + +[[setting]] +key = "show_vertical_grid" +type = "bool" +label_key = "layout_vertical_grid_label" +default = true + +[[setting]] +key = "show_vertical_deck" +type = "bool" +label_key = "layout_vertical_deck_label" +default = true + +[[setting]] +key = "show_vertical_fair" +type = "bool" +label_key = "layout_vertical_fair_label" +default = true diff --git a/mango_layouts/thumbnail.webp b/mango_layouts/thumbnail.webp new file mode 100644 index 0000000000000000000000000000000000000000..cf7c889faa82036efdb9036d84ae5243156d2cfb GIT binary patch literal 38154 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 Wtyl>1r@4Q2zfdK%kNO|G_ literal 0 HcmV?d00001 diff --git a/mango_layouts/translations/en.json b/mango_layouts/translations/en.json new file mode 100644 index 0000000..4338bcc --- /dev/null +++ b/mango_layouts/translations/en.json @@ -0,0 +1,35 @@ +{ + "show_icon_label": "Show Icon", + "show_text_label": "Show Text", + "custom_color_label": "Icon/Text Color", + "custom_color_desc": "E.g. primary, on_surface, etc.", + "list_mode_label": "Vertical List Mode", + "layout_tile_label": "Layout: Tile", + "layout_scroller_label": "Layout: Scroller", + "layout_monocle_label": "Layout: Monocle", + "layout_grid_label": "Layout: Grid", + "layout_fair_label": "Layout: Fair", + "layout_deck_label": "Layout: Deck", + "layout_dwindle_label": "Layout: Dwindle", + "layout_center_tile_label": "Layout: Center Tile", + "layout_vertical_tile_label": "Layout: Vertical Tile", + "layout_right_tile_label": "Layout: Right Tile", + "layout_vertical_scroller_label": "Layout: Vertical Scroller", + "layout_vertical_grid_label": "Layout: Vertical Grid", + "layout_vertical_deck_label": "Layout: Vertical Deck", + "layout_vertical_fair_label": "Layout: Vertical Fair", + "name_tile": "Tile", + "name_scroller": "Scroller", + "name_monocle": "Monocle", + "name_grid": "Grid", + "name_fair": "Fair", + "name_deck": "Deck", + "name_dwindle": "Dwindle", + "name_center_tile": "Center Tile", + "name_vertical_tile": "Vertical Tile", + "name_right_tile": "Right Tile", + "name_vertical_scroller": "Vertical Scroller", + "name_vertical_grid": "Vertical Grid", + "name_vertical_deck": "Vertical Deck", + "name_vertical_fair": "Vertical Fair" +} diff --git a/mango_layouts/widget.luau b/mango_layouts/widget.luau new file mode 100644 index 0000000..b130821 --- /dev/null +++ b/mango_layouts/widget.luau @@ -0,0 +1,68 @@ +local layouts = { + T = { name = "tile", glyph = "layout-sidebar" }, + S = { name = "scroller", glyph = "carousel-horizontal" }, + M = { name = "monocle", glyph = "square" }, + G = { name = "grid", glyph = "layout-grid" }, + F = { name = "fair", glyph = "layout-board-split" }, + D = { name = "deck", glyph = "layers-difference" }, + DW = { name = "dwindle", glyph = "layout-2" }, + CT = { name = "center_tile", glyph = "layout-distribute-vertical" }, + VT = { name = "vertical_tile", glyph = "layout-rows" }, + RT = { name = "right_tile", glyph = "layout-sidebar-right" }, + VS = { name = "vertical_scroller",glyph = "carousel-vertical" }, + VG = { name = "vertical_grid", glyph = "grid-dots" }, + VD = { name = "vertical_deck", glyph = "chart-funnel" }, + VF = { name = "vertical_fair", glyph = "layout-board" }, +} + +local show_glyph_raw = noctalia.getConfig("show_glyph") +local show_glyph = (show_glyph_raw == true) or (show_glyph_raw == "true") or (show_glyph_raw == nil) + +local show_text_raw = noctalia.getConfig("show_text") +local show_text = (show_text_raw == true) or (show_text_raw == "true") + +local custom_color = noctalia.getConfig("custom_color") + +function update() + noctalia.setUpdateInterval(1000) + noctalia.runAsync( + "mmsg get all-monitors | jq -r '.monitors[] | select(.active == true) | .layout_symbol'", + function(result) + if result and result.exitCode == 0 then + local sym = result.stdout:gsub("%s+", "") + local current = layouts[sym] + + if current then + if show_glyph then + barWidget.setGlyph(current.glyph) + end + + if show_text then + barWidget.setText(noctalia.tr("name_" .. current.name)) + else + barWidget.setText("") + end + + if custom_color and custom_color ~= "" then + barWidget.setColor(custom_color) + barWidget.setGlyphColor(custom_color) + end + else + if show_glyph then + barWidget.setGlyph("layout") + end + + if show_text then + barWidget.setText("Layout") + else + barWidget.setText("") + end + end + end + end + ) +end + +function onClick() + noctalia.togglePanel("ezequiel/mango_layouts:panel") +end