From c60c17100b2e03d03863c8ecadfe77f51c10d0db Mon Sep 17 00:00:00 2001 From: rokosun Date: Mon, 25 Dec 2023 07:50:13 +0000 Subject: [PATCH 1/8] Replace bash script with the new code in Nim --- layout-switcher | 60 ------------------ layoutSwitcher.nim | 147 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 147 insertions(+), 60 deletions(-) delete mode 100644 layout-switcher create mode 100644 layoutSwitcher.nim diff --git a/layout-switcher b/layout-switcher deleted file mode 100644 index 661af07..0000000 --- a/layout-switcher +++ /dev/null @@ -1,60 +0,0 @@ -#! /bin/bash -data=/usr/share/tromjaro-layout-switcher -icons=$data/icons -profiles=$data/profiles - -enable-top-bar-integration() { - # Enable global menus - pacman -Qq vala-panel-appmenu-registrar || - zensu SKIP_AUTOSNAP= pacman -S --noconfirm vala-panel-appmenu-registrar || - { notify-send 'Error' 'Failed installing vala-panel-appmenu-registrar !\nmake sure that you typed the password correctly or that you are not currently installing or updating your system\nEnabling the internet connection might solve the issue'; exit; } - pacman -Qq vala-panel-appmenu-registrar || exit - - # Hide window borders when maximized - xfconf-query -c xfwm4 -p /general/borderless_maximize -n -t bool -s true - # Hide top bar of windows when maximized - xfconf-query -c xfwm4 -p /general/titleless_maximize -n -t bool -s true - # Put window buttons on left side - xfconf-query -c xfwm4 -p /general/button_layout -n -t string -s "CMH|" -} - -disable-top-bar-integration() { - # Disable global menus - ! pacman -Qq vala-panel-appmenu-registrar || - zensu SKIP_AUTOSNAP= pacman -R --noconfirm vala-panel-appmenu-registrar || - { notify-send 'Error' 'Failed removing vala-panel-appmenu-registrar !\nmake sure that you typed the password correctly or that you are not currently installing or updating your system'; exit; } - pacman -Qq vala-panel-appmenu-registrar && exit - killall appmenu-registrar - - # Hide window borders when maximized - xfconf-query -c xfwm4 -p /general/borderless_maximize -n -t bool -s true - # Don't hide top bar of windows when maximized - xfconf-query -c xfwm4 -p /general/titleless_maximize -n -t bool -s false - # Put window buttons on right side - xfconf-query -c xfwm4 -p /general/button_layout -n -t string -s "|HMC" -} - -choice=$( -yad --no-buttons --center --keep-icon-size --separator='' --use-interp --title 'TROMjaro Layout Switcher' --text-align=center --text ' Please use the Panel Profiles to save your current configuration in case you did any manual changes, else you may lose them. -Changing to or from any layout that has global menus, will require your admin password.' --form --columns 3 \ ---field=!"$icons/windows.png"!'Windows-Like (default)':BTN "kill -USR1 \$YAD_PID; echo -n 'Windows-Like'" \ ---field=!"$icons/macos.png"!'MacOS-Like (experimental)':BTN "kill -USR1 \$YAD_PID; echo -n 'MacOS-Like'" \ ---field=!"$icons/mx.png"!'MX-Like':BTN "kill -USR1 \$YAD_PID; echo -n 'MX-Like'" \ ---field=!"$icons/gnome.png"!'Gnome-Like':BTN "kill -USR1 \$YAD_PID; echo -n 'Gnome-Like'" \ ---field=!"$icons/unity.png"!'Unity-Like (experimental)':BTN "kill -USR1 \$YAD_PID; echo -n 'Unity-Like'" \ ---field=!"$icons/topx.png"!'TopX-Like':BTN "kill -USR1 \$YAD_PID; echo -n 'TopX-Like'" -) - -case "$choice" in - 'Windows-Like'|'MX-Like'|'Gnome-Like'|'TopX-Like') - disable-top-bar-integration ;; - 'Unity-Like'|'MacOS-Like') - enable-top-bar-integration ;; - *) exit ;; -esac - -# Apply the XFCE panel profiles for the chosen layout -xfce4-panel-profiles load "$profiles/$choice.tar.bz2" -killall mate-hud && setsid -f /usr/lib/mate-hud/mate-hud - -sleep 2.5 && notify-send "$choice layout was enabled" \ No newline at end of file diff --git a/layoutSwitcher.nim b/layoutSwitcher.nim new file mode 100644 index 0000000..f8e8c79 --- /dev/null +++ b/layoutSwitcher.nim @@ -0,0 +1,147 @@ +from std/os import symlinkExists, getConfigDir, `/`, sleep +from std/envvars import existsEnv, getEnv, delEnv, putEnv +from std/options import Option, some, get, isNone +from std/strutils import toLowerAscii, split +import owlkettle, sharedModule + +const + dataDir = "/usr/share/tromjaro-layout-switcher" + iconsDir = dataDir / "icons" + profilesDir = dataDir / "profiles" + # GTK CSS for changing the default icon size and shape of our layout buttons + gtkCSS = """ +.layout-button > image { + -gtk-icon-transform: scale(19); +} + +.layout-button { + min-height: 200px; + min-width: 300px; +}""" + appID = "com.tromjaro.LayoutSwitcher" + layoutsGrid = [ + [ "Windows-Like (default)", "MacOS-Like (experimental)", "MX-Like" ], + [ "Gnome-Like", "Unity-Like (experimental)", "TopX-Like" ] + ] + +proc enableTopBarIntegration(): bool = + if not isGlobalMenuEnabled(): + # Enable global menu + let exitCode = runCommand("/usr/bin/pkexec", ["/usr/bin/toggle-global-menu", "enable"]) + case exitCode + of 0: + discard + of 126: + return false + of 127: + sendNotification(appID, "Layout Switcher", "Authentication failed!") + return false + else: + sendNotification(appID, "Failed installing global menu!", "Make sure that you are not currently installing any apps or updating the system.\nEnabling internet connection might solve the issue.") + return false + # Hide window borders when maximized + discard runCommand("/usr/bin/xfconf-query", + args=["--channel=xfwm4", "--property=/general/borderless_maximize", "--create", "--type=bool", "--set=true"]) + # Hide top bar of windows when maximized + discard runCommand("/usr/bin/xfconf-query", + args=["--channel=xfwm4", "--property=/general/titleless_maximize", "--create", "--type=bool", "--set=true"]) + # Put window buttons on left side + discard runCommand("/usr/bin/xfconf-query", + args=["--channel=xfwm4", "--property=/general/button_layout", "--create", "--type=string", "--set=CMH|"]) + return true + +proc disableTopBarIntegration(): bool = + if isGlobalMenuEnabled(): + # Disable global menu + let exitCode = runCommand("/usr/bin/pkexec", ["/usr/bin/toggle-global-menu", "disable"]) + case exitCode + of 0: + discard + of 126: + return false + of 127: + sendNotification(appID, "Layout Switcher", "Authentication failed!") + else: + sendNotification(appID, "Failed removing global menu!", "Make sure that you are not currently installing any apps or updating the system.") + return false + # Hide window borders when maximized + discard runCommand("/usr/bin/xfconf-query", + args=["--channel=xfwm4", "--property=/general/borderless_maximize", "--create", "--type=bool", "--set=true"]) + # Don't hide top bar of windows when maximized + discard runCommand("/usr/bin/xfconf-query", + args=["--channel=xfwm4", "--property=/general/titleless_maximize", "--create", "--type=bool", "--set=false"]) + # Put window buttons on right side + discard runCommand("/usr/bin/xfconf-query", + args=["--channel=xfwm4", "--property=/general/button_layout", "--create", "--type=string", "--set=|HMC"]) + return true + +proc enableLayout(layoutName: string) = + case layoutName + of "Windows-Like", "MX-Like", "Gnome-Like", "TopX-Like": + if not disableTopBarIntegration(): + return + of "Unity-Like", "MacOS-Like": + if not enableTopBarIntegration(): + return + else: + return + + discard runCommand("/usr/bin/xfce4-panel-profiles", ["load", profilesDir / layoutName & ".tar.bz2"]) + if runCommand("/usr/bin/killall", ["mate-hud"]) == 0: + discard runCommand("/usr/bin/setsid", ["-f", "/usr/lib/mate-hud/mate-hud"]) + sleep(5000) + sendNotification(appID, "Layout Switcher", layoutName & " layout was enabled", + icon = iconsDir / layoutName.toLowerAscii() & "-layout.png") + +var + oldConfigDir: Option[string] + configDirChanged: bool + +# Prevent loading GTK theme from ~/.config/gtk-4.0 directory when it is a symlink +if symlinkExists(getConfigDir() / "gtk-4.0"): + if existsEnv("XDG_CONFIG_HOME"): + oldConfigDir = some(getEnv("XDG_CONFIG_HOME")) + putEnv("XDG_CONFIG_HOME", "/dev/null") + configDirChanged = true + +viewable App: + hooks: + build: + # Reset the user's XDG_CONFIG_HOME variable back to what it was before + if configDirChanged == true: + if oldConfigDir.isNone(): + delEnv("XDG_CONFIG_HOME") + else: + putEnv("XDG_CONFIG_HOME", get(oldConfigDir)) + +method view(app: AppState): Widget = + result = gui: + Window: + title = "TROMjaro Layout Switcher" + # Shrink window to the smallest size + defaultSize = (0, 0) + iconName = "tromjaro-layout-switcher" + Box(orient = OrientY, margin = 7, spacing = 5): + Box(orient = OrientX): + Label {.hAlign: AlignEnd.}: + text = "Please use the" + LinkButton {.expand: false.}: + text = "Panel Profiles" + proc clicked() = + discard runCommand("/usr/bin/setsid", ["-f", "/usr/bin/xfce4-panel-profiles"]) + Label {.hAlign: AlignStart.}: + text = "to save your current configuration in case you did any manual changes, else you may lose them." + Label: + text = "Changing to or from any layout that has global menu will require your admin password." + for row in layoutsGrid: + Box(orient = OrientX, spacing = 5): + for tooltip in row: + let layoutName = tooltip.split(' ', 1)[0] + Button {.vAlign: AlignCenter, hAlign: AlignCenter.}: + icon = layoutName.toLowerAscii() & "-layout" + tooltip = tooltip + style = [ButtonFlat, StyleClass("layout-button")] + proc clicked() = + enableLayout(layoutName) + +brew(appID, gui(App()), icons=[iconsDir], stylesheets=[newStylesheet(gtkCSS)]) -- 2.30.2 From b7578dd97f5737151aef432b413554e4e94eb3e6 Mon Sep 17 00:00:00 2001 From: rokosun Date: Mon, 25 Dec 2023 07:52:09 +0000 Subject: [PATCH 2/8] Add sharedModule.nim --- sharedModule.nim | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 sharedModule.nim diff --git a/sharedModule.nim b/sharedModule.nim new file mode 100644 index 0000000..6c079ec --- /dev/null +++ b/sharedModule.nim @@ -0,0 +1,10 @@ +from std/osproc import startProcess, ProcessOption, waitForExit, close + +proc runCommand*(command: string, args: openArray[string]): int = + ## This will run a command with the given args and return its exit code upon completion + let process = startProcess(command, args=args, options={poParentStreams}) + result = process.waitForExit() + process.close() + +proc isGlobalMenuEnabled*(): bool = + return runCommand("/usr/bin/pacman", ["-Qq", "vala-panel-appmenu-registrar"]) == 0 -- 2.30.2 From 87ae3a63f50e8e89d7d981ec5fade3f4b2b73a25 Mon Sep 17 00:00:00 2001 From: rokosun Date: Mon, 25 Dec 2023 07:54:45 +0000 Subject: [PATCH 3/8] Add toggleGlobalMenu.nim --- toggleGlobalMenu.nim | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 toggleGlobalMenu.nim diff --git a/toggleGlobalMenu.nim b/toggleGlobalMenu.nim new file mode 100644 index 0000000..33cd91c --- /dev/null +++ b/toggleGlobalMenu.nim @@ -0,0 +1,44 @@ +from std/os import paramCount, paramStr, extractFilename +from std/strformat import fmt +import sharedModule + +proc enableGlobalMenus(): int = + return runCommand("/usr/bin/env", ["SKIP_AUTOSNAP=", "/usr/bin/pacman", "-S", "--noconfirm", "vala-panel-appmenu-registrar"]) + +proc disableGlobalMenus(): int = + result = runCommand("/usr/bin/env", ["SKIP_AUTOSNAP=", "/usr/bin/pacman", "-R", "--noconfirm", "vala-panel-appmenu-registrar"]) + if result == 0: + discard runCommand("/usr/bin/killall", ["appmenu-registrar"]) + +proc showHelp() = + let executableName = paramStr(0).extractFilename() + echo fmt""" +Usage: {executableName}