commit - /dev/null
commit + c6ee2ff9b662ee239c592880dff13ee44352ad58
blob - /dev/null
blob + 7c9a5e6fe3ce879813d1102a986abd96875a0443 (mode 644)
--- /dev/null
+++ README.md
+# My Pekwm Setup
+
+I run **pekwm** on **GhostBSD** with **Xorg** as my daily window manager.
+It’s light, fast, and highly configurable — exactly what I want for a simple yet powerful desktop environment.
+
+My workflow is mostly **keyboard-driven**, with custom keybindings for navigation, window management, and launching applications.
+I also rely on pekwm’s **grouping feature** to keep things organized: all my PDFs open in a single tabbed frame, and I can launch multiple terminal windows grouped together for easier handling.
+
+On top of that, I’ve added a few helper scripts, a custom menu generator, and some small tweaks for hardware control like volume, brightness, and touchscreen toggling.
+I've added a simple system that save and restore your pekwm session. So you retreive your environment exactly where it was before shutdown.
+The result is a **minimalist, efficient, and responsive environment** that fits my workflow perfectly, without unnecessary overhead.
+
+# Theme
+
+My theme is a slightly modified version of **Minimalst** by [Myugan](https://www.gnome-look.org/p/1137146).
+My main modificaitons concern the sizes and the slight modificaitons of border's colors.
+
+Thus a window having the focus is white, the orhers are lighblue
+
+# Config
+
+I mostly use the default configuration and have not made major changes.
+
+# Autoproperties
+
+Since I often open a large number of PDFs, I make use of the **grouping feature** in pekwm.
+This allows me to collect similar windows into tabs, and I can even define how many tabs a group can hold.
+
+Here is the rule I use for **Atril** (PDF reader):
+
+ Property = "^atril,^Atril" {
+ ApplyOn = "New"
+ Group = "pdf" {
+ Size = "15"
+ FocusedFirst = "True"
+ Raise = "True"
+ }
+ }
+
+I also use a similar rule for **Alacritty** terminals that I launch with a special class (`grouped`):
+
+ Property = "^grouped,^grouped" {
+ ApplyOn = "New"
+ Group = "grouped" {
+ Size = "15"
+ FocusedFirst = "True"
+ Raise = "True"
+ }
+ ClientGeometry = "1280x640+50+200"
+ }
+
+Such grouped Alacritty windows are created with:
+
+ alacritty --class grouped
+
+I have a specific config for my pseudo lockscreen made with xterm.
+It display in full screen and without border an xterm window displaying battery info.
+
+ Property = "xterm,Bigscreen" {
+ # ApplyOn = "Start New"
+ ApplyOn = "New"
+ Border = "False"; Titlebar = "False"
+ Sticky = "True"
+ Fullscreen = "True"
+ }
+
+To use this autoproperties, I lauch my app via the following command:
+
+ xterm -fa Monospace -fs 26 -bg black -fg black -title mybattery -class Bigscreen -e $HOME/.pekwm/scripts/xterm_mybattery.sh
+
+The keyword here is the "-class BigScreen" which tels to pekwm to make it fullscreen and without borders, title, ...
+
+A good way to defined what must be the Property value, you can use the following command:
+
+ xprop WM_CLASS | sed 's/.*"\(.*\)", "\(.*\)".*/ "\1,\2" /g'
+
+
+# Vars
+
+I define a few environment variables to simplify launching applications:
+
+ $BROWSER="firefox"
+ $EDITOR="alacritty -e nvim"
+ $FILEMANAGER="spacefm"
+ $EMAILS="thunderbird"
+ $TERM="alacritty --class grouped"
+
+For keyboard-driven window movement and resizing, I also set:
+
+ $MOVERESIZE_INCREMENT="15"
+
+# Keys
+
+## Pekwm Keybindings Documentation
+
+This section explains my **`keys`** configuration for **pekwm**, a lightweight and flexible window manager.
+It details the key bindings, actions, and custom scripts referenced in my setup.
+
+### 1. Includes
+
+At the top of the config, I include common variables and modular keybinding files:
+
+ INCLUDE = "vars"
+ INCLUDE = "$_PEKWM_ETC_PATH/keys_inputdialog"
+ INCLUDE = "$_PEKWM_ETC_PATH/keys_menu"
+ INCLUDE = "$_PEKWM_ETC_PATH/keys_moveresize"
+
+* **vars** – user-defined environment variables (`$TERM`, `$EDITOR`, `$BROWSER`, etc.).
+* **keys_inputdialog**, **keys_menu**, **keys_moveresize** – modular sets of bindings for input dialogs, menus, and resizing.
+
+### 2. Global Bindings
+
+These are the most frequently used shortcuts available everywhere.
+
+#### Frame Navigation
+
+* **Alt+Tab** – Next frame (raise temporarily).
+* **Alt+Shift+Tab** – Previous frame (raise temporarily).
+* **Alt+Ctrl+Tab** – Next frame (raise permanently).
+* **Alt+Ctrl+Shift+Tab** – Previous frame (raise permanently).
+* **Super+Tab / Super+Shift+Tab** – Cycle through clients within a frame.
+* **Super+Ctrl+Left/Right** – Move client left/right in frame.
+* **Super+Arrow keys** – Focus neighboring windows (directional).
+
+#### Workspace Navigation
+
+* **Ctrl+Alt+Arrow** – Switch workspace in the given direction.
+* **Ctrl+Super+Shift+Left/Right** – Jump to next/previous workspace (wrap).
+* **Super+1..9** – Switch directly to workspace 1–9.
+* **Ctrl+Alt+Shift+Arrow** – Send window to another workspace and follow it.
+* **Super+Shift+1..9** – Send window to workspace 1–9.
+
+#### Window Management
+
+* **Super+M** – Toggle maximized.
+* **Super+F** – Toggle fullscreen.
+* **Super+Shift+U** – Resize to 50% × 50%.
+* **Super+Shift+Z** – Resize to 50% × 100%.
+* **Super+Shift+H** – Resize to 100% × 50%.
+* **Super+Return** – Interactive move/resize.
+* **Super+Shift+Arrow** – Snap window to screen edge.
+* **Super+Q** – Close window.
+* **Super+S** – Shade window (roll up).
+* **Super+I** – Iconify (minimize).
+
+#### Marking / Tagging
+
+* **Super+Z** – Toggle window mark.
+* **Super+A** – Attach marked windows into one frame.
+* **Super+T** – Toggle tagged state.
+
+#### Menus
+
+* **Super+Space** – Show root menu.
+* **Super+W** – Show window menu.
+* **Super+L** – Show workspace navigation menu.
+* **Super+C** – Show client menu.
+* **Super+Shift+I** – Show icon menu.
+* **Super+X** – Hide all menus.
+
+#### External Commands
+
+* **Print** – Run screenshot script.
+* **Super+E** – Launch terminal.
+
+#### Pekwm Control
+
+* **Ctrl+Alt+Delete** – Restart pekwm.
+* **Super+V** – Show search dialog.
+* **Super+H** – Toggle harbour (dock/panel).
+
+### 3. Chains
+
+Chains are shortcuts with a **prefix key** followed by a second key.
+
+* **Ctrl+Super+C** – Move windows to corners/edges.
+* **Ctrl+Super+M** – Open menus (root, window, icon, goto, etc.).
+* **Ctrl+Super+T** – Grouping & tagging.
+* **Ctrl+Super+D** – Toggle borders/titlebars.
+* **Ctrl+Super+W** – Window management (resize, maximize, geometry presets).
+* **Ctrl+Super+F** – Frame navigation (cycle, move clients, focus).
+* **Ctrl+Super+S** – Full workspace management.
+* **Ctrl+Super+E** – Launch external apps (`$TERM`, `$BROWSER`, `$EMAILS`, `$FILEMANAGER`).
+* **Ctrl+Super+H** – Quick-open config files in `$EDITOR`.
+* **Ctrl+Super+P** – Reload, restart, exit pekwm, or show command dialog.
+
+### 4. Custom Additions
+
+I also added some personal bindings for hardware control and scripts:
+
+* **F1** – Toggle audio mute.
+* **F2/F3** – Volume down/up by 5%.
+* **F5/F6** – Screen brightness down/up.
+* **Ctrl+Alt+T** – Toggle touchscreen.
+* **Super+B** – a kind of lock screen which show battery info in xterm.
+* **Super+D** – Run `displayVaico.sh` my panel (cfr vaico project).
+
+### 5. Notes
+
+* `$TERM`, `$EDITOR`, `$BROWSER`, `$EMAILS`, `$FILEMANAGER` are defined in **vars**.
+* Helper scripts are in `$_PEKWM_CONFIG_PATH/scripts/` (e.g. `takeScreenShot.sh`, `toggle_touchscreen.sh`).
+* The **Harbour** is pekwm’s dock-like bar, which can be hidden or shown.
+
+# Menu
+
+I use a dedicated script to generate my **pekwm menu** from installed XDG `.desktop` entries.
+It automatically categorizes applications, adds system utilities, and builds a structured `~/.pekwm/menu` file ready to use.
+
+For details, see **README_createMenu.md**.
+
+# Save and restore pekwm sessions
+
+Thanks to pekwm_ctrl we list all opened windows. We check their associated PID and analyse their window's title.
+This is consolidated in a small Python script called saveSassesion.py.
+
+This information is saved into ~/.local/db/pekwm-session.
+
+In order to save this information, small halt.sh, reboot.sh and logout.sh scripts have been made. They also store logging information in ~/.pekwm/pekwm_scripts.log.
+
+Once you restart you pekwm session, the "start" script is automatically triggered by pekwm. So, this script initiate restoreSession.py. This python script look at ~/.local/db/pekwm-session and decide which applications must be restarted.
+
+
+
blob - /dev/null
blob + b026a7cd1dc8622e03d83ac28664ec6c652ee43d (mode 644)
--- /dev/null
+++ README_createMenu.md
+
+# createMenuApps.py
+
+This script generates a [pekwm](https://www.pekwm.se/) menu configuration file from installed XDG `.desktop` entries.
+It automatically categorizes applications, inserts system utilities, and builds a structured `~/.pekwm/menu` file ready to use.
+
+## ✨ Features
+
+* Parses installed `.desktop` files from XDG data directories.
+* Organizes applications into predefined categories (Multimedia, Office, Development, Games, etc.).
+* Automatically inserts mnemonic shortcuts (using `_` in menu labels).
+* Skips entries flagged as `NoDisplay` or restricted to specific desktop environments.
+* Includes custom entries for:
+
+ * Terminal, Run dialog, Browser, Editor, Mail, File Manager
+ * pekwm utilities (themes, wallpaper, reload/restart/exit actions)
+ * System actions (shutdown, reboot, logout)
+* Adds separators and comments for clarity.
+* Fully overwrites `~/.pekwm/menu` each run (manual edits will be lost).
+
+## Requirements
+
+* **Python 3**
+* [`pyxdg`](https://freedesktop.org/wiki/Software/pyxdg/) (usually installed as package `python3-xdg` or `pyxdg`)
+* A working **pekwm** environment
+
+
+## Installation
+
+Clone or copy the script into your pekwm configuration directory, for example:
+
+ mkdir -p ~/.pekwm/scripts
+ cp createMenuApps.py ~/.pekwm/scripts/
+ chmod +x ~/.pekwm/scripts/createMenuApps.py
+
+## Usage
+
+Run the script to generate (or update) the pekwm menu:
+
+ ~/.pekwm/scripts/createMenuApps.py
+
+By default, it writes to:
+
+ ~/.pekwm/menu
+
+Optionally, specify an alternative output path:
+
+ ~/.pekwm/scripts/createMenuApps.py /path/to/menu
+
+After generation, reload pekwm to apply the changes:
+
+ pekwm --reload
+
+
+## Menu Structure
+
+* **Static entries**: Terminal, Run, Browser, Editor, Mail, File Manager
+* **Dynamic submenus**: Applications grouped by XDG categories
+* **pekwm submenu**:
+
+ * Wallpaper script
+ * Theme switcher (dynamic menus)
+ * Reload/Restart/Exit options
+* **Exit submenu**:
+
+ * Shutdown
+ * Reboot
+ * Logout
+
+
+## Notes
+
+* The script will **overwrite** the target menu file each time it runs.
+* `.desktop` entries with `NoDisplay=true` or `OnlyShowIn=...` are commented out in the menu.
+* Some `.desktop` placeholders (`%U`, `%f`, etc.) are stripped from exec commands for pekwm compatibility.
+* Applications requiring a terminal are launched inside **alacritty** by default (`nohup alacritty -e ...`).
+
+
+## 📝 License
+
+```
+BSD 2-Clause License
+
+Copyright (c) 2025, Vincent.Delft@gmail.com
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+```
+
+---
+
+Do you want me to **include your name and year automatically in the license block**, or keep `<year>, <your name>` as placeholders so you can fill them in yourself?
+
blob - /dev/null
blob + eebb2ed5ebaab122d651f656b04af556342383f6 (mode 644)
--- /dev/null
+++ autoproperties
+# This file is in the public domain. Anyone is free to copy, modify, publish
+# use, sell or distribute for any purpose, commercial or non-commercial, and by
+# any means.
+
+/*
+ Autoproperties. The default template and simple course of autopropping
+ to help you add your own autoproperties. See the documentation for
+ more keywords and the rest of what is possible through this file.
+
+ First, it's good to note that you can't just make up the property
+ string, you need to use a program called 'xprop' to show it. Please
+ conduct the documentation.
+
+ Another good tip is to make sure you have an ApplyOn entry. The
+ autoproperties you define won't do any good if you don't tell pekwm
+ when to apply them!
+
+ Third tip. You can't match a window with more than one property. The
+ first one that matches will be used, the rest ignored (see the gimp
+ example).
+
+ Note that the default entries are commented out, don't comment out your
+ own autoproperties. :)
+*/
+
+Require {
+ Templates = "True"
+}
+
+/*
+ Group terminal applications
+ */
+# Property = "(term|rxvt),(erm|xvt)" {
+# ApplyOn = "New"
+# Group = "term" {
+# Size = "5"
+# FocusedFirst = "True"
+# Raise = "True"
+# }
+# }
+
+/*
+ Remove decor of customize toolbar window of mozilla firefox.
+ */
+Property = "^(gecko|Gecko|firefox-bin),^Firefox-bin,,^Customize Toolbar\\$" {
+ ApplyOn = "Start New TransientOnly"
+ Border = "False"
+ Titlebar = "False"
+}
+
+/*
+ Auto-group up to 10 mozilla download windows to group you call "moz-dl",
+ using a WM_CLASS and specifying the the download window using the
+ begining of its title. Make the windows go to the top-left corner of
+ your workspace and place them under other windows. Do this when new
+ windows show up, also to so called transient windows.
+*/
+# Property = "^mozilla-bin,^Mozilla-bin,,^Saving" {
+# ApplyOn = "New Transient"
+# Group = "moz-dl" { Size = "10" }
+# FrameGeometry = "+0+0"
+# Layer = "Below"
+# }
+
+
+/*
+ Group together up to two windows that have a WM_CLASS that matches the
+ property. Start these windows on workspace two.
+*/
+# Property = "^Mozilla,^navigator:browser" {
+# ApplyOn = "Start New Workspace"
+# Workspace = "2"
+# }
+
+
+/*
+ Group together an infinite number of windows that match the property.
+ When new windows are opened to this group, never make them the active
+ window of the group, but open them in the background. Make these
+ autoproperties apply on every pekwm start or when a new window is opened.
+*/
+# Property = "^dillo,^Dillo" {
+# ApplyOn = "Start New"
+# Group = "dillo" { Size = "0"; Behind = "True" }
+# }
+
+
+/*
+ Put property matching windows under other windows and make the window
+ appear on every workspace. Do not show matching windows on the pekwm
+ goto menus, do not include them in frame switching (mod1+tab) and do
+ not let other windows snap to them. Do this on pekwm start or when new
+ window is opened, also include transient windows (in the example,
+ xmms playlist and equalizer are transients).
+*/
+# Property = ".*,^xmms" {
+# ApplyOn = "Start New Transient"
+# Layer = "Desktop"
+# Sticky = "True"
+# Skip = "Menus FocusToggle Snap"
+# }
+
+
+/*
+ Remove Gimp windows from the menus, only show the main toolbox window.
+ Use the WM_WINDOW_ROLE to tell the difference between gimp windows.
+
+ First make sure the toolbox window doesn't get confused with the rest
+ of the windows. This just tells pekwm to ignore any matches for the
+ toolbox later on. Without this, the toolbox would match with "the rest
+ of the windows" and get ignored from the pekwm menus! We don't want that.
+*/
+# Property = "^gimp,^Gimp,gimp-toolbox" {
+# ApplyOn = "Start New"
+# }
+/*
+ The Crop dialog always gets in the way, put it in the corner but place
+ it above other windows anyways. Don't show the window in pekwm menus.
+*/
+# Property = "^gimp,^Gimp,gimp-crop-tool" {
+# ApplyOn = "Start New"
+# Layer = "OnTop"
+# FrameGeometry = "+0+0"
+# Skip = "Menus"
+# }
+/*
+ The rest of the gimp windows should not show in pekwm menus eather.
+*/
+# Property = ".gimp,^Gimp" {
+# ApplyOn = "Start New"
+# Skip = "Menus";
+# }
+
+
+/*
+ This should start making sense to you by now.
+*/
+# Property = "^gkrellm,^Gkrellm" {
+# ApplyOn = "Start New"
+# Sticky = "True"
+# Skip = "Menus FocusToggle"
+# Layer = "Desktop"
+# }
+
+
+/*
+ Some useful standard application xclock xload and xbiff. This should
+ be fairly clear to you. In addition to what you've allready learned,
+ we make the windows appear without titlebars and borders. We are also
+ using the geometry in all its glory, defining the windows size in
+ addition to its position.
+*/
+ Property = "^xclock,^XClock" {
+ ApplyOn = "Start New"
+ ClientGeometry = "120x137-0+0"
+ Border = "False"; Titlebar = "False"
+ Sticky = "True"
+# Layer = "Desktop"
+# Skip = "Menus FocusToggle Snap"
+ }
+#
+# Property = "^xload,^XLoad" {
+# ApplyOn = "Start New"
+# ClientGeometry = "560x137+120-137"
+# Border = "False"; Titlebar = "False"
+# Sticky = "True"
+# Layer = "Desktop"
+# Skip = "Menus FocusToggle Snap"
+# }
+#
+# Property = "^xbiff,^XBiff" {
+# ApplyOn = "Start New"
+# ClientGeometry = "120x137-120-137"
+# Border = "False"; Titlebar = "False"
+# Sticky = "True"
+# Layer = "Desktop"
+# Skip = "Menus FocusToggle Snap"
+# }
+
+
+// End of autoproperties. -------------------------
+
+TypeRules {
+ INCLUDE = "$_PEKWM_ETC_PATH/autoproperties_typerules"
+}
+
+/*
+ Next, we do some siple window title rewriting.
+ To make it simple, you can automatically make some windows get their
+ title edited. Cut out an annoying piece, add text, replace text.
+ This all happens in it's own section "TitleRules {}".
+
+ I don't like the way dillo uses its titlebar, it says "Dillo: webpage".
+ I want that "Dillo:" part to not show in the beginning, instead I want
+ to make it show as "webpage - dillo".
+
+ Then again, the "webpage - Mozilla Firefox" is too long for my taste.
+ I shorten it in the second titlerule. And I'll place the shortened text
+ in the beginning of the title just as a show how.
+*/
+# TitleRules {
+# Property = "^dillo,^Dillo" {
+# Rule = "/Dillo: (.*)/\\1 - dillo/"
+# }
+# Property = "^firefox-bin,^Firefox-bin" {
+# Rule = "/(.*) - Mozilla Firefox/MF: \\1/"
+# }
+# }
+
+
+// End of titlerules. -----------------------------
+
+
+/*
+ Then for some harbour ordering done in it's own "Harbour {}" section.
+ This is simple really, but you might want to check the documentation on
+ how the positions work.
+
+ Obpager is allways the last dockapp, the cpuload application is the
+ first, and wmnd will get placed in the centre.
+*/
+# Harbour {
+# Property = "^obpager,^obpager" {
+# Position = "-1"
+# }
+# Property = ".*,.*cpuload" {
+# Position = "1"
+# }
+# Property = ".*,^wmnd" {
+# Position = "0"
+# }
+# }
+
+
+// End of harbour order rules. --------------------
+
+
+/*
+ Last, if you have a theme that supports it, or you have hacked one up
+ yourself, you can use the "DecorRules {}" section to make windows show
+ up with independent decorations.
+
+ Here we tell our terminal windows to use the special TERM decoration
+ section found from your theme. Note that this _needs_ a theme that
+ supports it.
+*/
+# DecorRules {
+# Property = "^term,^xterm" {
+# Decor = "TERM"
+# }
+# }
+
+# My config
+
+ Property = "^atril,^Atril" {
+ ApplyOn = "New"
+ Group = "pdf" {
+ Size = "15"
+ FocusedFirst = "True"
+ Raise = "True"
+ }
+ }
+
+ Property = "^grouped,^grouped" {
+ ApplyOn = "New"
+ Group = "grouped" {
+ Size = "15"
+ FocusedFirst = "True"
+ Raise = "True"
+ }
+ ClientGeometry = "1280x640+50+200"
+ }
+
+ Property = "xterm,Bigscreen" {
+ # ApplyOn = "Start New"
+ ApplyOn = "New"
+ Border = "False"; Titlebar = "False"
+ Sticky = "True"
+ Fullscreen = "True"
+ }
blob - /dev/null
blob + 20a6bea98f8e9dbdd5551eb9fef67085ac73e0f7 (mode 644)
--- /dev/null
+++ config
+# This file is in the public domain. Anyone is free to copy, modify, publish
+# use, sell or distribute for any purpose, commercial or non-commercial, and by
+# any means.
+
+INCLUDE = "$_PEKWM_ETC_PATH/config_system"
+
+Files {
+ ThemeVariant = "auto"
+ Theme = "~/.pekwm/themes/My_minimalist"
+}
+
+Screen {
+ Scale = "1.5"
+
+ Workspaces = "4"
+ WorkspacesPerRow = "4"
+ WorkspaceNames = "Main1;main02;03;04"
+
+ # Remove below comment if you want the pointer to move whenever focus
+ # changes by the means of focus toggle or new clients.
+ # WarpPointerOn = "New FocusChange"
+ Placement {
+ Model = "CenteredOnParent Smart MouseNotUnder"
+ }
+}
+
+Menu {
+ # Defines how menus act on mouse input.
+ # Possible values are: "ButtonPress ButtonRelease DoubleClick Motion"
+ # To make submenus open on mouse over, comment the default Enter,
+ # uncomment the alternative, and reload pekwm.
+
+# Enter = "ButtonPress"
+ Enter = "Motion"
+}
+
+Debug {
+ File = "~/.pekwm/log"
+ Level = "info"
+}
+
+//Sys {
+// LocationLookup = "False"
+// Latitude = "0.0"
+// Longitude = "0.0"
+// XSettings = "True"
+// NetTheme = ""
+// NetIconTheme = ""
+// XResources {
+// Day {
+// "XTerm*background" = "#ffffff"
+// "XTerm*foreground" = "#31363b"
+// }
+// Night {
+// "XTerm*background" = "#22272e"
+// "XTerm*foreground" = "#a5b1be"
+// }
+// }
+//}
blob - /dev/null
blob + afb341f65d568692d373cd3f0c6e9e74d7dd8cb2 (mode 644)
--- /dev/null
+++ keys
+# This file is in the public domain. Anyone is free to copy, modify, publish
+# use, sell or distribute for any purpose, commercial or non-commercial, and by
+# any means.
+
+INCLUDE = "vars"
+
+INCLUDE = "$_PEKWM_ETC_PATH/keys_inputdialog"
+INCLUDE = "$_PEKWM_ETC_PATH/keys_menu"
+INCLUDE = "$_PEKWM_ETC_PATH/keys_moveresize"
+
+Global {
+# - - ----------------------------------------------- - -
+# pekwm interactions
+
+ # Moving in frames
+ KeyPress = "Mod1 Tab" { Actions = "NextFrameMRU TempRaise" }
+ KeyPress = "Mod1 Shift Tab" { Actions = "PrevFrameMRU TempRaise" }
+ KeyPress = "Mod1 Ctrl Tab" { Actions = "NextFrame EndRaise" }
+ KeyPress = "Mod1 Ctrl Shift Tab" { Actions = "PrevFrame EndRaise" }
+ KeyPress = "Mod4 Tab" { Actions = "ActivateClientRel 1" }
+ KeyPress = "Mod4 Shift Tab" { Actions = "ActivateClientRel -1" }
+ KeyPress = "Mod4 Ctrl Right" { Actions = "MoveClientRel 1" }
+ KeyPress = "Mod4 Ctrl Left" { Actions = "MoveClientRel -1" }
+ KeyPress = "Mod4 Left" { Actions = "FocusDirectional Left" }
+ KeyPress = "Mod4 Right" { Actions = "FocusDirectional Right" }
+ KeyPress = "Mod4 Up" { Actions = "FocusDirectional Up" }
+ KeyPress = "Mod4 Down" { Actions = "FocusDirectional Down" }
+ # Moving in workspaces
+ KeyPress = "Ctrl Mod1 Left" { Actions = "GotoWorkspace Left" }
+ KeyPress = "Ctrl Mod1 Right" { Actions = "GotoWorkspace Right" }
+ KeyPress = "Ctrl Mod1 Up" { Actions = "GotoWorkspace Up" }
+ KeyPress = "Ctrl Mod1 Down" { Actions = "GotoWorkspace Down" }
+ KeyPress = "Ctrl Mod4 Shift Left" { Actions = "GotoWorkspace LeftN" }
+ KeyPress = "Ctrl Mod4 Shift Right" { Actions = "GotoWorkspace RightN" }
+ KeyPress = "Mod4 1" { Actions = "GotoWorkspace 1" }
+ KeyPress = "Mod4 2" { Actions = "GotoWorkspace 2" }
+ KeyPress = "Mod4 3" { Actions = "GotoWorkspace 3" }
+ KeyPress = "Mod4 4" { Actions = "GotoWorkspace 4" }
+ KeyPress = "Mod4 5" { Actions = "GotoWorkspace 5" }
+ KeyPress = "Mod4 6" { Actions = "GotoWorkspace 6" }
+ KeyPress = "Mod4 7" { Actions = "GotoWorkspace 7" }
+ KeyPress = "Mod4 8" { Actions = "GotoWorkspace 8" }
+ KeyPress = "Mod4 9" { Actions = "GotoWorkspace 9" }
+ KeyPress = "Ctrl Mod1 Shift Left" { Actions = "SendToWorkspace Next KeepFocus; GoToWorkspace Next" }
+ KeyPress = "Ctrl Mod1 Shift Right" { Actions = "SendToWorkspace Prev KeepFocus; GoToWorkspace Prev" }
+ KeyPress = "Ctrl Mod1 Shift Up" { Actions = "SendToWorkspace NextV KeepFocus; GoToWorkspace NextV" }
+ KeyPress = "Ctrl Mod1 Shift Down" { Actions = "SendToWorkspace PrevV KeepFocus; GoToWorkspace PrevV" }
+ KeyPress = "Mod4 Shift 1" { Actions = "SendToWorkspace 1" }
+ KeyPress = "Mod4 Shift 2" { Actions = "SendToWorkspace 2" }
+ KeyPress = "Mod4 Shift 3" { Actions = "SendToWorkspace 3" }
+ KeyPress = "Mod4 Shift 4" { Actions = "SendToWorkspace 4" }
+ KeyPress = "Mod4 Shift 5" { Actions = "SendToWorkspace 5" }
+ KeyPress = "Mod4 Shift 6" { Actions = "SendToWorkspace 6" }
+ KeyPress = "Mod4 Shift 7" { Actions = "SendToWorkspace 7" }
+ KeyPress = "Mod4 Shift 8" { Actions = "SendToWorkspace 8" }
+ KeyPress = "Mod4 Shift 9" { Actions = "SendToWorkspace 9" }
+ # Simple window management
+ KeyPress = "Mod4 M" { Actions = "Toggle Maximized True True" }
+ KeyPress = "Mod4 F" { Actions = "Toggle FullScreen" }
+ KeyPress = "Mod4 Shift U" { Actions = "SetGeometry 50%x50% current HonourStrut" }
+ KeyPress = "Mod4 Shift Z" { Actions = "SetGeometry 50%x100% current HonourStrut" }
+ KeyPress = "Mod4 Shift H" { Actions = "SetGeometry 100%x50% current HonourStrut" }
+ KeyPress = "Mod4 Return" { Actions = "MoveResize" }
+ KeyPress = "Mod4 Shift Left" { Actions = "FillEdge LeftEdge 40" }
+ KeyPress = "Mod4 Shift Right" { Actions = "FillEdge RightEdge 40" }
+ KeyPress = "Mod4 Shift Up" { Actions = "FillEdge TopEdge 50" }
+ KeyPress = "Mod4 Shift Down" { Actions = "FillEdge BottomEdge 50" }
+ KeyPress = "Mod4 Q" { Actions = "Close" }
+ KeyPress = "Mod4 S" { Actions = "Toggle Shaded" }
+ KeyPress = "Mod4 I" { Actions = "Toggle Iconified" }
+ # Marking
+ KeyPress = "Mod4 Z" { Actions = "Toggle Marked" }
+ KeyPress = "Mod4 A" { Actions = "AttachMarked" }
+ # Tagging
+ KeyPress = "Mod4 T" { Actions = "Toggle Tagged False" }
+ # Menus
+ KeyPress = "Mod4 Space" { Actions = "ShowMenu Root" }
+ KeyPress = "Mod4 W" { Actions = "ShowMenu Window" }
+ KeyPress = "Mod4 L" { Actions = "ShowMenu Goto" }
+ KeyPress = "Mod4 C" { Actions = "ShowMenu GotoClient" }
+ KeyPress = "Mod4 Shift I" { Actions = "ShowMenu Icon" }
+ KeyPress = "Mod4 X" { Actions = "HideAllMenus" }
+ # External Commands
+ KeyPress = "Print" { Actions = "Exec $_PEKWM_CONFIG_PATH/scripts/takeScreenShot.sh " }
+ KeyPress = "Mod4 E" { Actions = "Exec $TERM" }
+ # Pekwm control
+ KeyPress = "Ctrl Mod1 Delete" { Actions = "Restart" }
+ # Conflict with Vaico KeyPress = "Mod4 D" { Actions = "ShowCmdDialog" }
+ KeyPress = "Mod4 V" { Actions = "ShowSearchDialog" }
+ KeyPress = "Mod4 H" { Actions = "Toggle HarbourHidden" }
+
+# - - ----------------------------------------------- - -
+# CHAINS grouped by categories.
+# ctrol-mod4 is always the base, then a letter for the category
+# then a letter for the actions
+ # Move to Corner . Mapping is based on azerty keyboard
+ # aze : for top left, center, right
+ # qsd : for middle left, center, right
+ # wxc : for bottom left, center, right
+ Chain = "Ctrl Mod4 C" {
+ KeyPress = "A" { Actions = "MoveToEdge TopLeft" }
+ KeyPress = "Z" { Actions = "MoveToEdge TopCenterEdge" }
+ KeyPress = "Shift Z" { Actions = "MoveToEdge TopEdge" }
+ KeyPress = "E" { Actions = "MoveToEdge TopRight" }
+ KeyPress = "Q" { Actions = "MoveToEdge LeftCenterEdge" }
+ KeyPress = "Shift Q" { Actions = "MoveToEdge LeftEdge" }
+ KeyPress = "S" { Actions = "MoveToEdge Center" }
+ KeyPress = "D" { Actions = "MoveToEdge RightCenterEdge" }
+ KeyPress = "Shift D" { Actions = "MoveToEdge RightEdge" }
+ KeyPress = "W" { Actions = "MoveToEdge BottomLeft" }
+ KeyPress = "X" { Actions = "MoveToEdge BottomCenterEdge" }
+ KeyPress = "Shift X" { Actions = "MoveToEdge BottomEdge" }
+ KeyPress = "C" { Actions = "MoveToEdge BottomRight" }
+ }
+ # Menus
+ Chain = "Ctrl Mod4 M" {
+ KeyPress = "R" { Actions = "ShowMenu Root" }
+ KeyPress = "W" { Actions = "ShowMenu Window" }
+ KeyPress = "I" { Actions = "ShowMenu Icon" }
+ KeyPress = "G" { Actions = "ShowMenu Goto" }
+ KeyPress = "C" { Actions = "ShowMenu GotoClient" }
+ KeyPress = "D" { Actions = "ShowMenu Decor" }
+ KeyPress = "A" { Actions = "ShowMenu AttachClientInFrame" }
+ KeyPress = "F" { Actions = "ShowMenu AttachFrameInFrame" }
+ Keypress = "Shift A" { Actions = "ShowMenu AttachClient" }
+ Keypress = "Shift F" { Actions = "ShowMenu AttachFrame" }
+ KeyPress = "X" { Actions = "HideAllMenus" }
+ }
+ # Grouping and tags
+ Chain = "Ctrl Mod4 T" {
+ KeyPress = "T" { Actions = "Toggle Tagged False" }
+ KeyPress = "B" { Actions = "Toggle Tagged True" }
+ KeyPress = "C" { Actions = "Unset Tagged" }
+ KeyPress = "G" { Actions = "Toggle GlobalGrouping" }
+ KeyPress = "M" { Actions = "Toggle Marked" }
+ KeyPress = "A" { Actions = "AttachMarked" }
+ KeyPress = "D" { Actions = "Detach" }
+ KeyPress = "H" { Actions = "DetachSplitHorz 50" }
+ KeyPress = "V" { Actions = "DetachSplitVert 50" }
+ Keypress = "P" { Actions = "AttachClientInNextFrame" }
+ KeyPress = "O" { Actions = "AttachClientInPrevFrame" }
+ Keypress = "I" { Actions = "AttachFrameInNextFrame" }
+ KeyPress = "U" { Actions = "AttachFrameInPrevFrame" }
+ }
+ # Decor Toggles
+ Chain = "Ctrl Mod4 D" {
+ KeyPress = "B" { Actions = "Toggle DecorBorder" }
+ KeyPress = "T" { Actions = "Toggle DecorTitlebar" }
+ KeyPress = "D" { Actions = "Toggle DecorBorder; Toggle DecorTitlebar" }
+ }
+ # Window
+ Chain = "Ctrl Mod4 W" {
+ # Growth: global, Horizontally, Vertically
+ Chain = "G" {
+ KeyPress = "G" { Actions = "MaxFill True True" }
+ KeyPress = "V" { Actions = "MaxFill False True" }
+ KeyPress = "H" { Actions = "MaxFill True False" }
+ }
+ # Maximize globally, vertically, Horizontally or sizes U, J, N from big to low
+ Chain = "M" {
+ KeyPress = "G" { Actions = "Toggle Maximized True True" }
+ KeyPress = "V" { Actions = "Toggle Maximized False True" }
+ KeyPress = "H" { Actions = "Toggle Maximized True False" }
+ KeyPress = "U" { Actions = "SetGeometry 75%x75% current HonourStrut" }
+ KeyPress = "J" { Actions = "SetGeometry 50%x50% current HonourStrut" }
+ KeyPress = "N" { Actions = "SetGeometry 50%x35% current HonourStrut" }
+ }
+ # Quit
+ Chain = "Q" {
+ KeyPress = "Q" { Actions = "Close" }
+ KeyPress = "F" { Actions = "CloseFrame" }
+ KeyPress = "K" { Actions = "Kill" }
+ }
+ # Skipping
+ Chain = "Ctrl Mod4 S" {
+ Keypress = "M" { Actions = "Toggle Skip Menus" }
+ Keypress = "F" { Actions = "Toggle Skip FocusToggle" }
+ Keypress = "S" { Actions = "Toggle Skip Snap" }
+ }
+ KeyPress = "S" { Actions = "Toggle Shaded" }
+ KeyPress = "A" { Actions = "Toggle Sticky" }
+ KeyPress = "O" { Actions = "Toggle AlwaysOnTop" }
+ KeyPress = "B" { Actions = "Toggle AlwaysBelow" }
+ KeyPress = "I" { Actions = "Set Iconified" }
+ KeyPress = "R" { Actions = "Raise" }
+ KeyPress = "Shift R" { Actions = "Raise True" }
+ KeyPress = "L" { Actions = "Lower" }
+ KeyPress = "Shift L" { Actions = "Lower True" }
+ KeyPress = "X" { Actions = "ActivateOrRaise" }
+ KeyPress = "Return" { Actions = "MoveResize" }
+ KeyPress = "F" { Actions = "Toggle Fullscreen" }
+ KeyPress = "Left" { Actions = "GrowDirection Left" }
+ KeyPress = "Right" { Actions = "GrowDirection Right" }
+ KeyPress = "Up" { Actions = "GrowDirection Up" }
+ KeyPress = "Down" { Actions = "GrowDirection Down" }
+ }
+ # Moving in Frames
+ Chain = "Ctrl Mod4 F" {
+ KeyPress = "P" { Actions = "NextFrame AlwaysRaise" }
+ KeyPress = "O" { Actions = "PrevFrame AlwaysRaise" }
+ KeyPress = "Shift P" { Actions = "NextFrameMRU EndRaise" }
+ KeyPress = "Shift O" { Actions = "PrevFrameMRU EndRaise" }
+ KeyPress = "I" { Actions = "ActivateClientRel 1" }
+ KeyPress = "U" { Actions = "ActivateClientRel -1" }
+ KeyPress = "Shift I" { Actions = "MoveClientRel 1" }
+ KeyPress = "Shift U" { Actions = "MoveClientRel -1" }
+ KeyPress = "Up" { Actions = "FocusDirectional Up" }
+ KeyPress = "Down" { Actions = "FocusDirectional Down" }
+ KeyPress = "Left" { Actions = "FocusDirectional Left" }
+ Keypress = "Right" { Actions = "FocusDirectional Right" }
+ KeyPress = "1" { Actions = "ActivateClientNum 1" }
+ KeyPress = "2" { Actions = "ActivateClientNum 2" }
+ KeyPress = "3" { Actions = "ActivateClientNum 3" }
+ KeyPress = "4" { Actions = "ActivateClientNum 4" }
+ KeyPress = "5" { Actions = "ActivateClientNum 5" }
+ KeyPress = "6" { Actions = "ActivateClientNum 6" }
+ KeyPress = "7" { Actions = "ActivateClientNum 7" }
+ KeyPress = "8" { Actions = "ActivateClientNum 8" }
+ KeyPress = "9" { Actions = "ActivateClientNum 9" }
+ KeyPress = "0" { Actions = "ActivateClientNum 10" }
+ KeyPress = "C" { Actions = "ShowCmdDialog GotoClientID " }
+ }
+ # Workspaces
+ Chain = "Ctrl Mod4 S" {
+ KeyPress = "Right" { Actions = "GoToWorkspace Right" }
+ KeyPress = "Left" { Actions = "GoToWorkspace Left" }
+ KeyPress = "N" { Actions = "GoToWorkspace Next" }
+ KeyPress = "P" { Actions = "GoToWorkspace Prev" }
+ KeyPress = "1" { Actions = "GoToWorkspace 1" }
+ KeyPress = "2" { Actions = "GoToWorkspace 2" }
+ KeyPress = "3" { Actions = "GoToWorkspace 3" }
+ KeyPress = "4" { Actions = "GoToWorkspace 4" }
+ KeyPress = "5" { Actions = "GoToWorkspace 5" }
+ KeyPress = "6" { Actions = "GoToWorkspace 6" }
+ KeyPress = "7" { Actions = "GoToWorkspace 7" }
+ KeyPress = "8" { Actions = "GoToWorkspace 8" }
+ KeyPress = "9" { Actions = "GoToWorkspace 9" }
+ KeyPress = "Up" { Actions = "SendToWorkspace Next KeepFocus; GoToWorkspace Next" }
+ KeyPress = "Down" { Actions = "SendToWorkspace Prev KeepFocus; GoToWorkspace Prev" }
+ KeyPress = "F1" { Actions = "SendToWorkspace 1" }
+ KeyPress = "F2" { Actions = "SendToWorkspace 2" }
+ KeyPress = "F3" { Actions = "SendToWorkspace 3" }
+ KeyPress = "F4" { Actions = "SendToWorkspace 4" }
+ KeyPress = "F5" { Actions = "SendToWorkspace 5" }
+ KeyPress = "F6" { Actions = "SendToWorkspace 6" }
+ KeyPress = "F7" { Actions = "SendToWorkspace 7" }
+ KeyPress = "F8" { Actions = "SendToWorkspace 8" }
+ KeyPress = "F9" { Actions = "SendToWorkspace 9" }
+ }
+ # External commands. Commands are specified in vars file
+ Chain = "Ctrl Mod4 E" {
+ KeyPress = "E" { Actions = "Exec $TERM" }
+ KeyPress = "B" { Actions = "Exec $BROWSER" }
+ KeyPress = "M" { Actions = "Exec $EMAILS" }
+ KeyPress = "F" { Actions = "Exec $FILEMANAGER" }
+ KeyPress = "P" { Actions = "Exec $_PEKWM_CONFIG_PATH/scripts/toggle.sh pekwm_panel" }
+ }
+ # help display main config files
+ # keys: k
+ # menu: m
+ # vars: v
+ # scripts directory: s (if your editor is vi, then you can edit the selected file
+ Chain = "Ctrl Mod4 H" {
+ KeyPress = "K" { Actions = "Exec $EDITOR $_PEKWM_CONFIG_PATH/keys" }
+ KeyPress = "M" { Actions = "Exec $EDITOR $_PEKWM_CONFIG_PATH/menu" }
+ KeyPress = "V" { Actions = "Exec $EDITOR $_PEKWM_CONFIG_PATH/vars" }
+ KeyPress = "S" { Actions = "Exec $EDITOR $_PEKWM_CONFIG_PATH/scripts" }
+ }
+ # Pekwm actions
+ Chain = "Ctrl Mod4 P" {
+ KeyPress = "Delete" { Actions = "Reload" }
+ KeyPress = "Home" { Actions = "Restart" }
+ KeyPress = "End" { Actions = "Exit" }
+ KeyPress = "D" { Actions = "ShowCmdDialog" }
+ KeyPress = "H" { Actions = "Toggle HarbourHidden" }
+ }
+
+ # short keys useful for my own needs
+ # because acpi keys are not working via FreeBSD on my Lenovo T14s
+ Keypress = "F1" { Actions = "Exec mixer vol.mute=toggle" }
+ Keypress = "F2" { Actions = "Exec mixer vol=-5%" }
+ Keypress = "F3" { Actions = "Exec mixer vol=+5%" }
+ Keypress = "F5" { Actions = "Exec $_PEKWM_CONFIG_PATH/scripts/decrease_brightness.sh" }
+ Keypress = "F6" { Actions = "Exec $_PEKWM_CONFIG_PATH/scripts/increase_brightness.sh" }
+ # toggle my touch screen on or off
+ Keypress = "Ctrl Mod1 T" { Actions = "Exec $_PEKWM_CONFIG_PATH/scripts/toggle_touchscreen.sh" }
+ # display a big black screen with battery usage
+ Keypress = "Mod4 B" { Actions = "Exec $_PEKWM_CONFIG_PATH/scripts/xterm_mybattery_window.sh" }
+ # Display my control panel called Vaico
+ Keypress = "Mod4 D" { Actions = "Exec $_PEKWM_CONFIG_PATH/scripts/displayVaico.sh" }
+}
blob - /dev/null
blob + 497bedcf2f1e5b52d6897ff9fc5f11555f5d61cf (mode 644)
--- /dev/null
+++ menu
+# This file has been generated by createMenuApp.py on Wed Sep 24 21:40:46 2025
+# Manual modifications will be lost
+# Configuration file is: /home/vi/.pekwm/menu
+
+INCLUDE = "vars"
+
+RootMenu = " pekwm" {
+ # This is a first comment
+ # and this is the second
+ Entry = " _Terminal" { Actions = "Exec $TERM" }
+ Entry = " _Run.." { Actions = "ShowCmdDialog" }
+ Separator{}
+ Entry = " _Browser" { Actions = "Exec $BROWSER" }
+ Entry = " 📚 _Editor" { Actions = "Exec $EDITOR" }
+ Entry = " 📭 E_mails" { Actions = "Exec $EMAILS" }
+ Entry = " 📂 _File Manager" { Actions = "Exec $FILEMANAGER" }
+ Separator{}
+ Submenu = " M_ultimedia" {
+ # only in MATE
+ # Entry = " Sound" { Actions = "Exec mate-volume-control" }
+ Entry = " _Rhythmbox" { Actions = "Exec rhythmbox " }
+ # has no display flag
+ # Entry = " Rhythmbox" { Actions = "Exec rhythmbox-client --select-source " }
+ Entry = " _VLC media player" { Actions = "Exec /usr/local/bin/vlc --started-from-file " }
+ }
+ Separator{}
+ Submenu = " _Development" {
+ Entry = " _Geany" { Actions = "Exec geany " }
+ # has no display flag
+ # Entry = " GTK+ Demo" { Actions = "Exec gtk3-demo" }
+ # has no display flag
+ # Entry = " Icon Browser" { Actions = "Exec gtk3-icon-browser" }
+ # has no display flag
+ # Entry = " Widget Factory" { Actions = "Exec gtk3-widget-factory" }
+ Entry = " _Neovim" { Actions = "Exec nohup alacritty -e nvim &" }
+ Entry = " _Meld" { Actions = "Exec meld " }
+ Entry = " _Pluma" { Actions = "Exec pluma " }
+ }
+ Separator{}
+ Submenu = " _Office" {
+ Entry = " _Atril Document Viewer" { Actions = "Exec atril " }
+ Entry = " _Freeplane" { Actions = "Exec /usr/local/bin/freeplane " }
+ Entry = " _LibreOffice Base" { Actions = "Exec libreoffice --base " }
+ Entry = " L_ibreOffice Calc" { Actions = "Exec libreoffice --calc " }
+ Entry = " Li_breOffice Draw" { Actions = "Exec libreoffice --draw " }
+ Entry = " Lib_reOffice Impress" { Actions = "Exec libreoffice --impress " }
+ Entry = " Libr_eOffice Math" { Actions = "Exec libreoffice --math " }
+ Entry = " Libre_Office" { Actions = "Exec libreoffice " }
+ Entry = " LibreOffi_ce Writer" { Actions = "Exec libreoffice --writer " }
+ # only in MATE
+ # Entry = " MATE Dictionary" { Actions = "Exec mate-dictionary" }
+ }
+ Separator{}
+ Submenu = " Edu_cation" {
+ Entry = " _LibreOffice Math" { Actions = "Exec libreoffice --math " }
+ }
+ Separator{}
+ Submenu = " Gr_aphics" {
+ Entry = " _Eye of MATE Image Viewer" { Actions = "Exec eom " }
+ # has no display flag
+ # Entry = " feh" { Actions = "Exec feh --start-at " }
+ Entry = " _GNU Image Manipulation Program" { Actions = "Exec gimp-2.10 " }
+ Entry = " _LibreOffice Draw" { Actions = "Exec libreoffice --draw " }
+ # only in MATE
+ # Entry = " MATE Color Selection" { Actions = "Exec mate-color-select" }
+ # has no display flag
+ # Entry = " Shotwell Viewer" { Actions = "Exec shotwell " }
+ Entry = " _Shotwell" { Actions = "Exec shotwell " }
+ Entry = " _digiKam" { Actions = "Exec digikam -qwindowtitle " }
+ Entry = " s_howFoto" { Actions = "Exec showfoto -qwindowtitle " }
+ Entry = " _nomacs" { Actions = "Exec nomacs " }
+ }
+ Separator{}
+ Submenu = " _Network" {
+ Entry = " _FileZilla" { Actions = "Exec filezilla" }
+ Entry = " F_irefox Web Browser" { Actions = "Exec firefox " }
+ Entry = " I_ridium" { Actions = "Exec iridium " }
+ Entry = " _Thunderbird" { Actions = "Exec thunderbird " }
+ Entry = " Ti_gerVNC viewer" { Actions = "Exec vncviewer" }
+ Entry = " _WiFi Networks Manager" { Actions = "Exec wifimgr " }
+ }
+ Separator{}
+ Submenu = " _System" {
+ Entry = " _Alacritty" { Actions = "Exec alacritty" }
+ Entry = " _Backup Station" { Actions = "Exec sudo backup-station" }
+ Entry = " _dconf Editor" { Actions = "Exec dconf-editor" }
+ # only in Budgie, MATE, XFCE
+ # Entry = " Caja" { Actions = "Exec /usr/local/bin/caja --no-desktop --browser " }
+ # has no display flag
+ # only in MATE
+ # Entry = " Computer" { Actions = "Exec /usr/local/bin/caja --no-desktop computer:" }
+ # has no display flag
+ # only in MATE
+ # Entry = " Home Folder" { Actions = "Exec /usr/local/bin/caja --no-desktop" }
+ Entry = " _fbpanel" { Actions = "Exec fbpanel" }
+ Entry = " f_ish" { Actions = "Exec nohup alacritty -e fish &" }
+ # has no display flag
+ # Entry = " Install GhostBSD" { Actions = "Exec gbi" }
+ # has no display flag
+ # only in GNOME
+ # Entry = " Keyboard Layout" { Actions = "Exec gkbd-keyboard-display" }
+ Entry = " _Htop" { Actions = "Exec nohup alacritty -e htop &" }
+ # only in MATE
+ # Entry = " MATE Disk Usage Analyzer" { Actions = "Exec mate-disk-usage-analyzer" }
+ # has no display flag
+ # only in MATE
+ # Entry = " Network" { Actions = "Exec /usr/local/bin/caja --no-desktop network:" }
+ # has no display flag
+ # only in MATE
+ # Entry = " Panel" { Actions = "Exec mate-panel" }
+ # only in MATE
+ # Entry = " Power Statistics" { Actions = "Exec mate-power-statistics" }
+ # only in MATE
+ # Entry = " Log File Viewer" { Actions = "Exec mate-system-log" }
+ # only in MATE
+ # Entry = " MATE System Monitor" { Actions = "Exec mate-system-monitor" }
+ Entry = " _MATE Terminal" { Actions = "Exec mate-terminal" }
+ Entry = " _VTE Terminal for GTK3" { Actions = "Exec vte-2.91" }
+ Entry = " _Phoronix Test Suite" { Actions = "Exec nohup alacritty -e phoronix-test-suite shell &" }
+ Entry = " _Software Station" { Actions = "Exec sudo software-station" }
+ Entry = " Spa_ceFM" { Actions = "Exec spacefm " }
+ Entry = " P_rint Settings" { Actions = "Exec system-config-printer" }
+ Entry = " _Update Station" { Actions = "Exec sudo update-station check-now" }
+ Entry = " _WiFi Networks Manager" { Actions = "Exec wifimgr " }
+ Entry = " _XTerm" { Actions = "Exec xterm" }
+ }
+ Separator{}
+ Submenu = " Accessor_ies" {
+ Entry = " _Backup Station" { Actions = "Exec sudo backup-station" }
+ # only in MATE
+ # Entry = " File Management" { Actions = "Exec /usr/local/bin/caja-file-management-properties" }
+ Entry = " _Engrampa Archive Manager" { Actions = "Exec engrampa " }
+ Entry = " _Character Map" { Actions = "Exec gucharmap" }
+ # only in LXDE
+ # Entry = " Preferred Applications" { Actions = "Exec libfm-pref-apps" }
+ # has no display flag
+ # Entry = " Shortcut Editor" { Actions = "Exec lxshortcut -i " }
+ # only in MATE
+ # Entry = " About Me" { Actions = "Exec mate-about-me" }
+ # has no display flag
+ # only in MATE
+ # Entry = " About MATE" { Actions = "Exec mate-about" }
+ # only in MATE
+ # Entry = " Appearance" { Actions = "Exec mate-appearance-properties " }
+ # only in MATE
+ # Entry = " Assistive Technologies" { Actions = "Exec mate-at-properties" }
+ Entry = " _MATE Calculator" { Actions = "Exec mate-calc" }
+ # only in MATE
+ # Entry = " Preferred Applications" { Actions = "Exec mate-default-applications-properties" }
+ # only in MATE
+ # Entry = " Displays" { Actions = "Exec mate-display-properties" }
+ Entry = " M_ATE Font Viewer" { Actions = "Exec mate-font-viewer " }
+ # only in MATE
+ # Entry = " Keyboard Shortcuts" { Actions = "Exec mate-keybinding-properties" }
+ # only in MATE
+ # Entry = " Keyboard" { Actions = "Exec mate-keyboard-properties" }
+ # only in MATE
+ # Entry = " Network Proxy" { Actions = "Exec mate-network-properties" }
+ # only in MATE
+ # Entry = " Popup Notifications" { Actions = "Exec mate-notification-properties" }
+ # only in MATE
+ # Entry = " Power Management" { Actions = "Exec mate-power-preferences" }
+ # only in MATE
+ # Entry = " Screensaver" { Actions = "Exec mate-screensaver-preferences" }
+ # only in MATE
+ # Entry = " Take Screenshot" { Actions = "Exec mate-screenshot --interactive" }
+ # only in MATE
+ # Entry = " MATE Search Tool" { Actions = "Exec mate-search-tool" }
+ # only in MATE
+ # Entry = " Startup Applications" { Actions = "Exec mate-session-properties" }
+ # only in MATE
+ # Entry = " Mouse" { Actions = "Exec mate-mouse-properties" }
+ # only in MATE
+ # Entry = " system-info" { Actions = "Exec mate-system-info" }
+ # has no display flag
+ # only in MATE
+ # Entry = " Theme Installer" { Actions = "Exec mate-appearance-properties -i " }
+ # only in MATE
+ # Entry = " Sound" { Actions = "Exec mate-volume-control" }
+ # only in MATE
+ # Entry = " Windows" { Actions = "Exec mate-window-properties" }
+ # only in MATE
+ # Entry = " Control Center" { Actions = "Exec mate-control-center" }
+ # only in MATE
+ # Entry = " Main Menu" { Actions = "Exec mozo" }
+ Entry = " _Neovim" { Actions = "Exec nohup alacritty -e nvim &" }
+ Entry = " _VTE Terminal for GTK3" { Actions = "Exec vte-2.91" }
+ Entry = " _Passwords and Keys" { Actions = "Exec seahorse " }
+ # has no display flag
+ # Entry = " KNewStuff Dialog" { Actions = "Exec knewstuff-dialog6" }
+ Entry = " p_icom" { Actions = "Exec picom" }
+ Entry = " P_lank Reloaded" { Actions = "Exec plank" }
+ Entry = " Pl_uma" { Actions = "Exec pluma " }
+ Entry = " _Software Station" { Actions = "Exec sudo software-station" }
+ Entry = " Space_FM File Search" { Actions = "Exec spacefm --find-files " }
+ Entry = " SpaceFM" { Actions = "Exec spacefm " }
+ # only in MATE
+ # Entry = " Station Tweak" { Actions = "Exec station-tweak" }
+ Entry = " P_rint Settings" { Actions = "Exec system-config-printer" }
+ Entry = " Up_date Station" { Actions = "Exec sudo update-station check-now" }
+ # only in GNOME, Unity
+ # Entry = " Help" { Actions = "Exec yelp " }
+ }
+ Separator{}
+ Submenu = " _pekwm" {
+ Entry = " _Background" { Actions = "Exec $_PEKWM_CONFIG_PATH/scripts/wallpaper.sh" }
+ Submenu = " _Themes" {
+ Entry { Actions = "Dynamic $_PEKWM_SCRIPT_PATH/pekwm_themeset.sh $_PEKWM_THEME_PATH" }
+ Entry { Actions = "Dynamic $_PEKWM_SCRIPT_PATH/pekwm_themeset.sh $_PEKWM_CONFIG_PATH/themes" }
+ }
+ Entry = " Build this _menu" { Actions = "Exec $_PEKWM_CONFIG_PATH/scripts/createMenuApps.py $_PEKWM_CONFIG_PATH/menu ; Reload" }
+ Entry = " _Reload" { Actions = "Reload" }
+ Entry = " Re_start" { Actions = "Restart" }
+ Entry = " ➡️E_xit" { Actions = "Exec $_PEKWM_CONFIG_PATH/scripts/logout.sh" }
+ }
+ Separator{}
+ Submenu = " 🔄E_xit" {
+ Entry = " ⏻_Shutdown" { Actions = "Exec $_PEKWM_CONFIG_PATH/scripts/halt.sh" }
+ Entry = " 🔄_Reboot" { Actions = "Exec $_PEKWM_CONFIG_PATH/scripts/reboot.sh" }
+ Entry = " ➡️ E_xit" { Actions = "Exec $_PEKWM_CONFIG_PATH/scripts/logout.sh" }
+ }
+}
blob - /dev/null
blob + 46ac2596c9d9eb4acc68a41405d585d9e825fb9e (mode 644)
--- /dev/null
+++ mouse
+# This file is in the public domain. Anyone is free to copy, modify, publish
+# use, sell or distribute for any purpose, commercial or non-commercial, and by
+# any means.
+
+# Swap comments on the two following lines to switch betwen
+# click does not raise and click to raise.
+#$CLIENT_CLICK = "Focus"
+$CLIENT_CLICK = "Focus; Raise"
+
+# Base mouse configuration
+INCLUDE = "$_PEKWM_ETC_PATH/mouse_system"
+
+# Swap comments on the two folling lines to switch between
+# sloppy and click to focus
+INCLUDE = "$_PEKWM_ETC_PATH/mouse_sloppy"
+# INCLUDE = "$_PEKWM_ETC_PATH/mouse_click"
+
+# Add configuration overrides here, it possible to add sections,
+# sub-section and values overriding/adding specific values.
blob - /dev/null
blob + 5b489682bb1f496b6f43ed9cd02899fed3313b45 (mode 644)
Binary files /dev/null and screenshots/screenshot1.png differ
blob - /dev/null
blob + f1ab569510b7ce9755803bbc319f5a3586ed0490 (mode 644)
Binary files /dev/null and screenshots/screenshot2.png differ
blob - /dev/null
blob + 049150a191fcb66bd8af6d991730e5e8b86ddaa0 (mode 644)
Binary files /dev/null and screenshots/screenshot3.png differ
blob - /dev/null
blob + c23965e1fb37309eb90d8da94cb8ce2d3815d9ba (mode 644)
--- /dev/null
+++ scripts/createMenuApps.py
+#!/usr/local/bin/python3
+
+import xdg
+import xdg.BaseDirectory
+import xdg.DesktopEntry
+from pathlib import Path
+import os
+import sys
+import time
+
+# Define menu categories (label, XDG categories)
+MENU_CATEGORIES = [
+ (('M_ultimedia'), ('AudioVideo', 'Audio', 'Video')),
+ (('_Development'), ('Development', 'TextEditor')),
+ (('_Office'), ('Office',)),
+ (('Edu_cation'), ('Education',)),
+ (('_Games'), ('Game',)),
+ (('Gr_aphics'), ('Graphics',)),
+ (('_Network'), ('Network',)),
+ (('_System'), ('System',)),
+ (('Accessor_ies'), ('Settings', 'Utility')),
+ (('Ot_hers'), ()),
+]
+
+# Default pekwm menu destination
+MENU = os.path.expanduser("~/.pekwm/menu")
+
+
+# -------------------------------
+# Menu / Submenu / Entry classes
+# -------------------------------
+
+class Menu:
+ """Represents the root pekwm menu."""
+
+ def __init__(self, name, comments=None):
+ self.name = name
+ self.items = []
+ self.comments = comments or []
+
+ def render(self, fid, indent=0):
+ """Render the menu structure recursively into file descriptor fid."""
+ addInConfigFile(fid, " " * indent + f"""RootMenu = " {self.name}" {{ """)
+ for comment in self.comments:
+ addInConfigFile(fid, " " * (indent + 4) + comment)
+ for item in self.items:
+ item.render(fid, indent + 4)
+ addInConfigFile(fid, " " * indent + "}")
+
+
+class Submenu:
+ """Represents a submenu inside the root pekwm menu."""
+
+ def __init__(self, name, comments=None):
+ self.name = name
+ self.items = []
+ self.comments = comments or []
+
+ def render(self, fid, indent=0):
+ """Render submenu and its children recursively."""
+ addInConfigFile(fid, " " * indent + f"""Submenu = " {self.name}" {{ """)
+ for comment in self.comments:
+ addInConfigFile(fid, " " * (indent + 4) + comment)
+ for item in self.items:
+ item.render(fid, indent + 4)
+ addInConfigFile(fid, " " * indent + "}")
+
+
+class Entry:
+ """Represents an executable menu entry (application launcher)."""
+
+ def __init__(self, name, action, preCmd="", comments=None):
+ self.name = name
+ self.action = action
+ self.comments = comments or []
+ self.preCmd = preCmd
+
+ def render(self, fid, indent=0):
+ """Write entry into the config file."""
+ for comment in self.comments:
+ addInConfigFile(fid, " " * indent + comment)
+ if self.name:
+ addInConfigFile(fid, " " * indent + self.preCmd +
+ f"""Entry = " {self.name}" {{ Actions = "{self.action}" }}""")
+ else:
+ addInConfigFile(fid, " " * indent + self.preCmd +
+ f"""Entry {{ Actions = "{self.action}" }}""")
+
+
+class Separator:
+ """Represents a visual separator between menu entries."""
+
+ def render(self, fid, indent=0):
+ addInConfigFile(fid, " " * indent + "Separator{}")
+
+
+# -------------------------------
+# Utility functions
+# -------------------------------
+
+def getXDG():
+ """
+ Parse all .desktop files from XDG data directories.
+ Group them by categories defined in MENU_CATEGORIES.
+ Returns: dict { menu_label: [DesktopEntry objects] }
+ """
+ results = {}
+ for folder in xdg.BaseDirectory.xdg_data_dirs:
+ for file in sorted(Path(folder.rstrip("/") + "/applications/").glob("*.desktop")):
+ xdg_obj = xdg.DesktopEntry.DesktopEntry(filename=str(file))
+ if xdg_obj:
+ for main, categories in MENU_CATEGORIES:
+ if set(categories) & set(xdg_obj.getCategories()):
+ results.setdefault(main, [])
+ results[main].append(xdg_obj)
+ return results
+
+
+def addInConfigFile(fid, line):
+ """Safely write one line into the pekwm menu config file."""
+ if not fid:
+ print("ERROR: Problem to write in config file:", MENU)
+ sys.exit(1)
+ fid.write(line + '\n')
+
+
+# -------------------------------
+# Main script
+# -------------------------------
+if __name__ == "__main__":
+ # Destination file: ~/.pekwm/menu by default, can override with argument
+ destination = os.path.expanduser(MENU)
+ if len(sys.argv) > 1:
+ destination = sys.argv[1]
+
+ # Collect XDG desktop entries
+ xdg_data = getXDG()
+
+ with open(destination, "w", encoding="utf-8") as fid:
+ # Header comments
+ addInConfigFile(fid, f"# This file has been generated by createMenuApp.py on {time.ctime()}")
+ addInConfigFile(fid, "# Manual modifications will be lost")
+ addInConfigFile(fid, f"# Configuration file is: {destination}\n")
+ addInConfigFile(fid, 'INCLUDE = "vars"\n')
+
+ # Root menu creation
+ menu = Menu("pekwm", comments=["# This is a first comment", "# and this is the second"])
+
+ # Basic fixed entries
+ menu.items.append(Entry("_Terminal", "Exec $TERM"))
+ menu.items.append(Entry("_Run..", "ShowCmdDialog"))
+ menu.items.append(Separator())
+ menu.items.append(Entry(" _Browser", "Exec $BROWSER"))
+ menu.items.append(Entry("📚 _Editor", "Exec $EDITOR"))
+ menu.items.append(Entry("📭 E_mails", "Exec $EMAILS"))
+ menu.items.append(Entry("📂 _File Manager", "Exec $FILEMANAGER"))
+ menu.items.append(Separator())
+
+ # Dynamic submenus from XDG categories
+ for main, content in MENU_CATEGORIES:
+ submenu = Submenu(main)
+ short_key = [] # Track used shortcut keys in submenu
+ for xdg_obj in xdg_data.get(main, []):
+ if xdg_obj:
+ # keep exec parsing as-is per your request
+ exec = xdg_obj.getExec().split("%")[0]
+ if xdg_obj.getTerminal():
+ exec = "nohup alacritty -e %s &" % exec
+ name = xdg_obj.getName()
+ comments = []
+ preCmd = ""
+ if xdg_obj.getNoDisplay():
+ preCmd = "# "
+ comments.append("# has no display flag")
+ if len(xdg_obj.getOnlyShowIn()) > 0:
+ preCmd = "# "
+ comments.append("# only in %s" % ", ".join(xdg_obj.getOnlyShowIn()))
+
+ if preCmd == "":
+ # Add underscore (_) for mnemonic shortcut key
+ i = 0
+ found = False
+ while i < len(name) and not found:
+ letter = name[i].lower()
+ if letter not in short_key:
+ found = True
+ short_key.append(letter)
+ name = name[0:i] + "_" + name[i:]
+ i += 1
+ entry = Entry(name, "Exec %s" % exec, preCmd, comments)
+ submenu.items.append(entry)
+
+ if submenu.items:
+ menu.items.append(submenu)
+ menu.items.append(Separator())
+
+ # Static submenu for pekwm-specific actions
+ submenu = Submenu("_pekwm")
+ submenu.items.append(Entry("_Background", "Exec $_PEKWM_CONFIG_PATH/scripts/wallpaper.sh"))
+ submenu2 = Submenu("_Themes")
+ submenu2.items.append(Entry(None, "Dynamic $_PEKWM_SCRIPT_PATH/pekwm_themeset.sh $_PEKWM_THEME_PATH"))
+ submenu2.items.append(Entry(None, "Dynamic $_PEKWM_SCRIPT_PATH/pekwm_themeset.sh $_PEKWM_CONFIG_PATH/themes"))
+ submenu.items.append(submenu2)
+ submenu.items.append(Entry("Build this _menu",
+ "Exec $_PEKWM_CONFIG_PATH/scripts/createMenuApps.py $_PEKWM_CONFIG_PATH/menu ; Reload"))
+ submenu.items.append(Entry("_Reload", "Reload"))
+ submenu.items.append(Entry("Re_start", "Restart"))
+ submenu.items.append(Entry("➡️E_xit", "Exec $_PEKWM_CONFIG_PATH/scripts/logout.sh"))
+ menu.items.append(submenu)
+ menu.items.append(Separator())
+
+ # Exit submenu (shutdown/reboot/logout)
+ submenu = Submenu("🔄E_xit")
+ submenu.items.append(Entry("⏻_Shutdown", "Exec $_PEKWM_CONFIG_PATH/scripts/halt.sh"))
+ submenu.items.append(Entry("🔄_Reboot", "Exec $_PEKWM_CONFIG_PATH/scripts/reboot.sh"))
+ submenu.items.append(Entry("➡️ E_xit", "Exec $_PEKWM_CONFIG_PATH/scripts/logout.sh"))
+ menu.items.append(submenu)
+
+ # Write out the full menu structure
+ menu.render(fid)
+
blob - /dev/null
blob + 13341f949e359ab8fb00c1521b0d45f6e95f47df (mode 755)
--- /dev/null
+++ scripts/decrease_brightness.sh
+#!/bin/sh
+
+current_brightness=$(xrandr --verbose | grep Brightness | awk '{print $2}')
+current_gamma=$(xrandr --verbose | grep Gamma | awk '{print $2}')
+echo "Current:$current_brightness**"
+new_brightness=$( echo "$current_brightness - 0.1" | bc )
+
+echo "Gamme:$current_gamma"
+echo "New:$new_brightness**"
+xrandr --output eDP-1 --brightness "$new_brightness" --gamma "$current_gamma"
blob - /dev/null
blob + 543f04793d7de576498f95fa804f4bc1e68ecef5 (mode 755)
--- /dev/null
+++ scripts/halt.sh
+#!/bin/sh
+
+PEKWM_LOGFILE="$HOME/.pekwm/pekwm_scripts.log"
+
+echo "[$(date)] initiating halt.sh" >> $PEKWM_LOGFILE
+$HOME/.pekwm/scripts/saveSession.py >> $PEKWM_LOGFILE
+echo "[$(date)] Executing: doas halt -p" >> $PEKWM_LOGFILE
+doas halt -p
blob - /dev/null
blob + 2f2b40de86a68e8c658cfbab8fd3e7967e1ab2a1 (mode 755)
--- /dev/null
+++ scripts/increase_brightness.sh
+#!/bin/sh
+
+current_brightness=$(xrandr --verbose | grep Brightness | awk '{print $2}')
+current_gamma=$(xrandr --verbose | grep Gamma | awk '{print $2}')
+echo "Current:$current_brightness**"
+new_brightness=$( echo "$current_brightness + 0.1" | bc )
+
+echo "Gamma:$current_gamma**"
+echo "New:$new_brightness**"
+xrandr --output eDP-1 --brightness "$new_brightness" --gamma "$current_gamma"
blob - /dev/null
blob + e50b46ddade5648dc131b0d99f98356843a8e3a3 (mode 755)
--- /dev/null
+++ scripts/logout.sh
+#!/bin/sh
+
+PEKWM_LOGFILE="$HOME/.pekwm/pekwm_scripts.log"
+
+echo "[$(date)] Initiating logout.sh" >> $PEKWM_LOGFILE
+$HOME/.pekwm/scripts/saveSession.py >> $PEKWM_LOGFILE
+echo "[$(date)] Executing; pekwm --replace" >> $PEKWM_LOGFILE
+pekwm --replace
blob - /dev/null
blob + 1fe945734a5fbb91cc953acdb9a7700124b4b45e (mode 755)
--- /dev/null
+++ scripts/reboot.sh
+#!/bin/sh
+
+PEKWM_LOGFILE="$HOME/.pekwm/pekwm_scripts.log"
+
+echo "[$(date)] Initiating a reboot" >> $PEKWM_LOGFILE
+$HOME/.pekwm/scripts/saveSession.py >> $PEKWM_LOGFILE
+echo "[$(date)] Executing: doas reboot" >> $PEKWM_LOGFILE
+
+doas reboot
blob - /dev/null
blob + 87bc32a26533591ba760023c45b3f2f470d1e362 (mode 755)
--- /dev/null
+++ scripts/restoreSession.py
+#!/usr/local/bin/python3
+
+import os
+import os.path
+import ast
+import subprocess
+import time
+import sys
+
+
+SESSIONFILE = "~/.local/db/pekwm-session"
+DEBUG = False
+if len(sys.argv) > 1 and sys.argv[1] == "-D":
+ print("We are in DEBUG mode")
+ DEBUG = True
+
+print(f"{time.ctime()} Restoring pekwm session from: {SESSIONFILE}")
+
+def specificTreatment(cmds, element):
+ """Specific treatment due to specific grouping made in pekwm"""
+ if "atril" == element[0]:
+ # sometimes atril is not with his fullpath name
+ element[0] = "/usr/local/bin/atril"
+ if "atril" in element[0]:
+ # skip atril command with multiple parameters
+ if [element[0], element[1]] not in [e["action"] for e in cmds]:
+ return [element[0], element[1]]
+ if "alacritty" in element[0]:
+ # we authorise mutltiple for sessions and ssh sessions
+ return element
+ if element not in [e["action"] for e in cmds]:
+ # we do not accept multiple
+ return element
+ return None
+
+with open(os.path.expanduser(SESSIONFILE),"r") as f:
+ sessionLines = f.readlines()
+
+cmds = []
+cmd_str = ""
+pwd = ""
+for sessionLine in sessionLines:
+ if sessionLine.startswith(" Command:"):
+ cmd_str = sessionLine[10:].strip()
+ if sessionLine.startswith(" PWD:"):
+ pwd = sessionLine[6:].strip()
+ if (not sessionLine.startswith(" ") or sessionLine == sessionLines[-1]) and cmd_str:
+ # we are in another block or at the end of the file
+ element = ast.literal_eval(cmd_str)
+ modifiedElements = specificTreatment(cmds, element)
+ if modifiedElements:
+ cmds.append({"action": modifiedElements, "pwd":pwd})
+ cmd_str = ""
+ pwd = ""
+
+# I list when this is sorted ;)
+cmds.sort(key=lambda x: x["action"][0])
+for cmd in cmds:
+ try:
+ if cmd["pwd"]:
+ print(f"""We are executing: {" ".join(cmd["action"])} in {cmd["pwd"]}""")
+ env = os.environ.copy()
+ env["PWD"] = cmd["pwd"]
+ if DEBUG:
+ print(f"""Popen {cmd["action"]}, in {cmd["pwd"]} """)
+ else:
+ proc = subprocess.Popen(cmd["action"], cwd=cmd["pwd"], env=env, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
+ else:
+ print(f"""We are executing: {" ".join(cmd["action"])}""")
+ if DEBUG:
+ print(f"""Popen {cmd["action"]}""")
+ else:
+ proc = subprocess.Popen(cmd["action"], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
+ except OSError as e:
+ print(f"ERROR: Failed to restart: {str(e)}")
+ time.sleep(0.5)
+ if not DEBUG:
+ ret = proc.poll()
+ if ret is not None and ret != 0:
+ print(f"ERROR: Failed to execute it, returncode is: {ret}")
+
+print("Restore session process finalized")
blob - /dev/null
blob + 869e5481d233a1a2ad1628531b716f39e7b0b0a8 (mode 755)
--- /dev/null
+++ scripts/saveSession.py
+#!/usr/local/bin/python3
+
+import subprocess
+import re
+import os
+import psutil
+import time
+import os.path
+
+
+SESSIONFILE="~/.local/db/pekwm-session"
+
+ACTIONS = [(re.compile(r"vi@:\s*(.+)"), lambda m : ["alacritty",
+ "--class",
+ "grouped",
+ "--working-directory",
+ os.path.expanduser(m.group(1)),
+ "--command",
+ "zsh",
+ "-ic",
+ "exec zsh" ]),
+ (re.compile(r"(\w+)@(\w+):\s*(.+)"), lambda m: ["alacritty",
+ "--class",
+ "grouped",
+ "--title",
+ f"{m.group(1)}@{m.group(2)}:",
+ "-e",
+ "ssh",
+ f"{m.group(1)}@{m.group(2)}"] , # we do not change to folder
+ )]
+
+
+configfid = open(os.path.expanduser(SESSIONFILE),"w")
+
+def xprop(window_id):
+ """Retrieve the PID associated with a given window ID using xprop."""
+ try:
+ # Run xprop command to get window properties
+ result = subprocess.run(['xprop', '-id', str(window_id)], capture_output=True, text=True, check=True)
+ output = result.stdout
+
+ # Look for _NET_WM_PID(CARDINAL) in the output
+ pid_match = re.search(r'_NET_WM_PID\(CARDINAL\) = (\d+)', output)
+ if pid_match:
+ pid = pid_match.group(1)
+ else:
+ pid = None
+ cmd_match = re.search(r'WM_COMMAND\(STRING\) = (.+)', output)
+ if cmd_match:
+ cmd = cmd_match.group(1)
+ if cmd:
+ cmd = cmd.replace('{','[').replace('}',']')
+ else:
+ cmd = None
+ return pid, cmd
+ except subprocess.CalledProcessError:
+ configfid.write(f"Error: Could not retrieve PID for window ID {window_id}\n")
+ return None, None
+
+def getSpecificCases(window_name):
+ for pattern, action in ACTIONS:
+ m = pattern.search(window_name)
+ if m:
+ cmd = action(m)
+ return cmd
+ return None
+
+if __name__ == "__main__":
+ winid_treated = []
+ # Sample input data (window_id, window_name pairs)
+ result = subprocess.run(['pekwm_ctrl', '-a', 'list'], capture_output=True, text=True, check=True)
+ output = result.stdout
+ result = subprocess.run(['pekwm_ctrl', '-a', 'list-children'], capture_output=True, text=True, check=True)
+ output += result.stdout
+
+ print(time.ctime(), " Saving pekwm session...")
+ for line in output.split('\n'):
+ if not re.search(r'^(?: {2})?\d+ .+$', line):
+ continue
+ window_id, window_name = line.strip().split(' ', 1)
+ if window_id in winid_treated:
+ continue
+ winid_treated.append(window_id)
+ configfid.write(f"Window ID: {window_id}, Name: {window_name}\n")
+ pid = None
+ cmd = None
+ # for my home made windows
+ cmd = getSpecificCases(window_name)
+ # Get PID
+ if not cmd:
+ pid, cmd = xprop(window_id)
+ if pid:
+ configfid.write(f" PID: {pid}\n")
+ # Get command associated with PID
+ p = psutil.Process(int(pid))
+ configfid.write( f" Command: {p.cmdline()}\n")
+ configfid.write(f""" PWD: {p.environ().get("PWD", "")}\n""")
+ elif cmd:
+ configfid.write(f" Command: {cmd}\n")
+ else:
+ configfid.write(f" PID or CMD: Not found\n")
+ print(f"Window ID: {window_id}, Name: {window_name}")
+ print(" pid or cmd not: found found")
+ configfid.close()
+ print(f"Session saved in {SESSIONFILE}")
+ print(time.ctime()," Save session process finalized")
blob - /dev/null
blob + 62d01689277d86546921e0a8c52e4ef13a11bffa (mode 755)
--- /dev/null
+++ scripts/takeScreenShot.sh
+#!/bin/sh
+
+scrot -s "/tmp/scrot-%Y-%m-%d_%H%M.png" -e 'xclip -selection clipboard -t image/png -i $f'
blob - /dev/null
blob + 49e061ee1b5196f65a013ad704cecec83cb781d7 (mode 755)
--- /dev/null
+++ scripts/toggle_touchscreen.sh
+#!/bin/sh
+
+# Note: require: pkg install xinput
+
+# xinput list
+# enabled:
+# ↳ ELAN901C:00 04F3:2EA3 TouchScreen id=12 [slave pointer (2)]
+# disabled:
+# ∼ ELAN901C:00 04F3:2EA3 TouchScreen id=12 [floating slave]
+
+
+if xinput list | grep TouchScreen | grep pointer ; then
+ xinput disable 12
+ xcowsay "TouchScreen disabled"
+else
+ xinput enable 12
+ xcowsay "TouchScreen enabled"
+fi
+
+
blob - /dev/null
blob + 5899543193c7699833087499ffec834e61adb1c0 (mode 755)
--- /dev/null
+++ scripts/wallpaper.sh
+#!/bin/sh
+ HOMEDIR="/home/$USER/.pekwm/scripts/wallpapers"
+ RANDOMFILE=$(find "${HOMEDIR}" -type f | sort -R | head -1)
+ echo "Randofile: $RANDOMFILE"
+ if [ -h "${HOMEDIR}/current" ]; then
+ res=$(/usr/bin/cmp "$RANDOMFILE" "${HOMEDIR}/current")
+ #res is either a text either a blank (file are identic)
+ lnres=${#res}
+ while [ "$lnres" -eq 0 ]; do
+ RANDOMFILE=$(find "${HOMEDIR}" -type f | sort -R | head -1)
+ # echo "random2:$RANDOMFILE"
+ res=$(/usr/bin/cmp "$RANDOMFILE" "${HOMEDIR}/current")
+ lnres=${#res}
+ done
+ fi
+ /bin/ln -fs "$RANDOMFILE" "${HOMEDIR}/current"
+ /usr/local/bin/feh --xinerama-index 0 --bg-max "$RANDOMFILE"
+ #display -backdrop -window root $RANDOMFILE
blob - /dev/null
blob + f68fb27edf4d8a9f8f342e6f71757ad42c2ec61d (mode 644)
Binary files /dev/null and scripts/wallpapers/392362.jpg differ
blob - /dev/null
blob + f6f160f1b328ef6570cf535a448e4279c2d42184 (mode 644)
Binary files /dev/null and scripts/wallpapers/FreeBSD.jpg differ
blob - /dev/null
blob + a1de03f2d2bc498171d482e45ac0a45417bf68ac (mode 644)
Binary files /dev/null and scripts/wallpapers/HB-FreeBSD.png differ
blob - /dev/null
blob + 0591b235eb27aa0b9fed542b9ac0f475a7bff24f (mode 644)
Binary files /dev/null and scripts/wallpapers/freebsd-logo-650.jpg differ
blob - /dev/null
blob + b63df91d0b829785a2252222f9766e1ecd183806 (mode 644)
Binary files /dev/null and scripts/wallpapers/freebsd-wallpaper-1.png differ
blob - /dev/null
blob + e90b69143a03aaf0b418adec64f4edabdd3b67c8 (mode 644)
Binary files /dev/null and scripts/wallpapers/freebsd-wallpaper-2.jpg differ
blob - /dev/null
blob + ed233f569b9f1e64084ee10f34eb17b0d475aefc (mode 644)
Binary files /dev/null and scripts/wallpapers/freebsd-wallpaper-3.png differ
blob - /dev/null
blob + 04dc242108088d401885ec2d27ef2f5a63c2d9a8 (mode 644)
Binary files /dev/null and scripts/wallpapers/freebsd-wallpaper-5.jpg differ
blob - /dev/null
blob + 85c82428421e5758d3e66196a6fc107154472410 (mode 644)
Binary files /dev/null and scripts/wallpapers/i3lock.png differ
blob - /dev/null
blob + 2dc1a89518b2f225afcd9b4bb47ca385d87bd146 (mode 644)
Binary files /dev/null and scripts/wallpapers/logo-thepowertoserve.png differ
blob - /dev/null
blob + 9fe20de7aadbef2e63bcf72a7033490e10c1843b (mode 644)
Binary files /dev/null and scripts/wallpapers/o9kSzwx-openbsd-wallpaper.png differ
blob - /dev/null
blob + 5478d3cae80211b0b4141d8bd62e51b89a7010e7 (mode 755)
--- /dev/null
+++ scripts/xterm_mybattery.sh
+#!/usr/local/bin/bash
+
+# Display battery usage and top most process
+
+
+# ANSI color codes using printf-compatible syntax
+RED=$(printf '\033[31m')
+GREEN=$(printf '\033[32m')
+BLUE=$(printf '\033[34m')
+RESET=$(printf '\033[0m')
+SLEEP=15
+
+
+while :; do
+ battery=$(acpiconf -i 0 | grep "Remaining capacity" | awk '{print $3}' | tr -d '%')
+ state=$(acpiconf -i 0 | grep "State:" | awk '{print $2}' )
+ top1=$(ps axo pcpu,command | awk '!/\[.*\]/' | awk 'NR==1 {print $1, $2; next} {printf "%.1f%% %s\n", $1, $2}' | tail +2 | sort -k1 -nr | head -n 1 )
+ clock=$(date)
+ remaining=$(apm | grep "Remaining battery time" | head -n 1)
+
+ if [ "$battery" -lt 15 ]; then
+ color="$RED"
+ elif [ "$battery" -gt 95 ]; then
+ color="$BLUE"
+ else
+ color="$GREEN"
+ fi
+ i=0
+ while [ $i -lt $(jot -r 1 1 10) ]
+ do
+ echo "*"
+ i=$(( i + 1 ))
+ done
+ printf "\033[2K%s %s\n\n Battery: %s%%\n %s\n %s\n\n%s%s" "$color" "$clock" "$battery" $"$remaining" "$state" "$top1" "$RESET"
+ read -r -s -n1 -t "$SLEEP" key
+ clear
+done
blob - /dev/null
blob + 140df1a43656e0cf21ff706459be2ee4cc0bf0ce (mode 755)
--- /dev/null
+++ scripts/xterm_mybattery_window.sh
+#!/bin/sh
+
+
+# Display batery usage in a big black screen
+# This is not a screen locker, but it looks like ;)
+# It's like the password is ctrl-c ;)
+
+# to be complete, please add the following to your pekwm/autoproperties file
+# Property = "xterm,Bigscreen" {
+# ApplyOn = "New"
+# Border = "False"; Titlebar = "False"
+# Sticky = "True"
+# Fullscreen = "True"
+# }
+
+# adapt the font size to your screen
+xterm -fa Monospace -fs 26 -bg black -fg black -title mybattery -class Bigscreen -e $HOME/.pekwm/scripts/xterm_mybattery.sh
blob - /dev/null
blob + 5582ee0fa1631dc1e9ede0e42ce7c41152022400 (mode 755)
--- /dev/null
+++ start
+#!/bin/sh
+#
+# This file is in the public domain. Anyone is free to copy, modify, publish
+# use, sell or distribute for any purpose, commercial or non-commercial, and by
+# any means.
+#
+# pekwm start shell script run when pekwm starts excluding restarts.
+#
+# The file must be marked executable for it to be executed:
+#
+# chmod +x ~/.pekwm/start
+#
+# Execution of the file can be skipped by passing --skip-start to pekwm.
+#
+
+
+PEKWM_LOGFILE="$HOME/.pekwm/pekwm_scripts.log"
+exec >>"$PEKWM_LOGFILE" 2>&1
+
+
+echo "[$(date)] Pekwm start script running..."
+
+echo "Setting a wallpaper"
+~/.pekwm/scripts/wallpaper.sh
+echo "Starting picom"
+picom &
+echo "Setting brightness"
+~/.local/bin/brightness.sh
+#echo "Stating xdaliclock"
+#xdaliclock -24 -builtin1 &
+
+# better to put it the last one
+~/.pekwm/scripts/restoreSession.py
+
+echo "[$(date)] Pekwm start script finished."
blob - /dev/null
blob + 1d3ae414f6a04e43622369af3101df7f728912b9 (mode 644)
Binary files /dev/null and themes/My_minimalist/arrow.png differ
blob - /dev/null
blob + beb6bdd9d721be003ca4f6082073330ea9aedd80 (mode 644)
Binary files /dev/null and themes/My_minimalist/bottom.png differ
blob - /dev/null
blob + 082e49d518f6e7be4ede9e902bf81df5da4527dd (mode 644)
Binary files /dev/null and themes/My_minimalist/button.png differ
blob - /dev/null
blob + 8d8a854d594b1855d1a1130ebf359e83b6677867 (mode 644)
Binary files /dev/null and themes/My_minimalist/button_hover.png differ
blob - /dev/null
blob + 54298da42868e28cb7248d150d42eedd664469b9 (mode 644)
Binary files /dev/null and themes/My_minimalist/button_unfocus.png differ
blob - /dev/null
blob + feae33cdc03fee37206fc842198b5f554e16741c (mode 644)
Binary files /dev/null and themes/My_minimalist/menu.png differ
blob - /dev/null
blob + ba291082979906f507d2518bca15af833bf6a022 (mode 644)
Binary files /dev/null and themes/My_minimalist/menuline.png differ
blob - /dev/null
blob + 20254c9e788ee58b1d0d273f2df9a8a94cd48961 (mode 644)
--- /dev/null
+++ themes/My_minimalist/theme
+$font = "Fira Sans Medium:size=9#left#XFT"
+$font1 = "Fira Sans Medium:size=9#center#XFT"
+
+Require
+{
+ Templates = "True"
+}
+
+Define = "Base"
+{
+ Height = "22" # defined by button's sizes
+ Pad = "0 0 10 0"
+
+ Focused = "Empty"
+ Unfocused = "Empty"
+
+ Tab {
+ Focused = "Solid #71A9F7 1x1"
+ FocusedSelected = "Solid #FBFBFB 1x1"
+ UnFocused = "Solid #71A9F7 1x1"
+ UnFocusedSelected = "Solid #71A9F7 1x1"
+ }
+ Font
+ {
+ Focused = "$font1"
+ FocusedSelected = "$font1"
+ Unfocused = "$font1"
+ UnfocusedSelected = "$font1"
+ }
+ FontColor
+ {
+ Focused = "#262626"
+ FocusedSelected = "#696969"
+ Unfocused = "#262626"
+ UnfocusedSelected= "#262626"
+ }
+ Separator
+ {
+ Focused = "Empty"
+ Unfocused = "Empty"
+ }
+ Border
+ {
+ Focused
+ {
+ TopLeft = "Solid #FBFBFB 1x1"
+ Top = "Solid #FBFBFB 1x1"
+ TopRight = "Solid #FBFBFB 1x1"
+ Left = "Solid #FBFBFB 4x4"
+ Right = "Solid #FBFBFB 4x4"
+ BottomLeft = "Solid #FBFBFB 4x4"
+ Bottom = "Solid #FBFBFB 4x4"
+ BottomRight = "Solid #FBFBFB 4x4"
+ }
+ Unfocused
+ {
+ TopLeft = "Solid #79A9F7 1x1"
+ Top = "Solid #79A9F7 1x1"
+ TopRight = "Solid #79A9F7 1x1"
+ Left = "Solid #79A9F7 4x4"
+ Right = "Solid #79A9F7 4x4"
+ BottomLeft = "Solid #79A9F7 4x4"
+ Bottom = "Solid #79A9F7 4x4"
+ BottomRight = "Solid #79A9F7 4x4"
+ }
+ }
+}
+
+Define = "Buttons"
+{
+ Buttons
+ {
+ Right = "Close"
+ {
+ Focused = "Image button.png"
+ Unfocused = "Image button_unfocus.png"
+ Hoover = "Image button_hover.png"
+ Pressed = "Image button_hover.png"
+ Button = "1" { Actions = "Close" }
+ Button = "3" { Actions = "Kill" }
+ }
+ Right = "Maximize"
+ {
+ Focused = "Image button.png"
+ Unfocused = "Image button_unfocus.png"
+ Hoover = "Image button_hover.png"
+ Pressed = "Image button_hover.png"
+ Button = "1" { Actions = "Toggle Maximized 1 1" }
+ }
+ Right = "Iconify"
+ {
+ Focused = "Image button.png"
+ Unfocused = "Image button_unfocus.png"
+ Hoover = "Image button_hover.png"
+ Pressed = "Image button_hover.png"
+ Button = "1" { Actions = "Set Iconified" }
+ }
+ }
+}
+
+Define = "Menu"
+{
+ Height = "0"10
+ Pad = "0 0 0 0"
+
+ Focused = "Empty"
+ Unfocused = "Empty"
+
+ Tab
+ {
+ Focused = "Empty"
+ FocusedSelected = "Empty"
+ Unfocused = "Empty"
+ UnfocusedSelected = "Empty"
+ }
+ Separator
+ {
+ Focused = "Empty"
+ Unfocused = "Empty"
+ }
+ Border
+ {
+ Focused
+ {
+ TopLeft = "Image menu.png"
+ Top = "Image menu.png"
+ TopRight = "Image menu.png"
+ Left = "Image menu.png"
+ Right = "Image menu.png"
+ BottomLeft = "Image menu.png"
+ Bottom = "Image menu.png"
+ BottomRight = "Image menu.png"
+ }
+ Unfocused
+ {
+ TopLeft = "Image menu.png"
+ Top = "Image menu.png"
+ TopRight = "Image menu.png"
+ Left = "Image menu.png"
+ Right = "Image menu.png"
+ BottomLeft = "Image menu.png"
+ Bottom = "Image menu.png"
+ BottomRight = "Image menu.png"
+ }
+ }
+}
+
+Define = "Workspace"
+{
+ Height = "0"
+# Pad = "0 0 0 0"
+
+ Font
+ {
+ Focused = "$font"
+ }
+ FontColor
+ {
+ Focused = "Empty"
+ FocusedSelected = "Empty"
+ Unfocused = "Empty"
+ UnfocusedSelected = "Empty"
+ }
+ Border
+ {
+ Focused
+ {
+ TopLeft = "Empty"
+ Top = "Empty"
+ TopRight = "Empty"
+ Left = "Empty"
+ Right = "Empty"
+ BottomLeft = "Empty"
+ Bottom = "Empty"
+ BottomRight = "Empty"
+ }
+ Unfocused
+ {
+ TopLeft = "Empty"
+ Top = "Empty"
+ TopRight = "Empty"
+ Left = "Empty"
+ Right = "Empty"
+ BottomLeft = "Empty"
+ Bottom = "Empty"
+ BottomRight = "Empty"
+ }
+ }
+}
+
+Define = "Empty"
+{
+ Focused = "Empty"
+ Unfocused = "Empty"
+
+ Tab
+ {
+ Focused = "Empty"
+ FocusedSelected = "Empty"
+ Unfocused = "Empty"
+ UnfocusedSelected = "Empty"
+ }
+
+ Separator {
+ Focused = "Empty"
+ Unfocused = "Empty"
+ }
+ Font
+ {
+ Focused = "Empty"
+ }
+ FontColor
+ {
+ Focused = "Empty"
+ FocusedSelected = "Empty"
+ Unfocused = "Empty"
+ UnfocusedSelected = "Empty"
+ }
+ Border
+ {
+ Focused
+ {
+ TopLeft = "Empty"
+ Top = "Empty"
+ TopRight = "Empty"
+ Left = "Empty"
+ Right = "Empty"
+ BottomLeft = "Empty"
+ Bottom = "Empty"
+ BottomRight = "Empty"
+ }
+ Unfocused
+ {
+ TopLeft = "Empty"
+ Top = "Empty"
+ TopRight = "Empty"
+ Left = "Empty"
+ Right = "Empty"
+ BottomLeft = "Empty"
+ Bottom = "Empty"
+ BottomRight = "Empty"
+ }
+ }
+}
+
+PDecor
+{
+ Decor = "Default"
+ {
+ Title
+ {
+ @Base
+ @Buttons
+ }
+ }
+
+ Decor = "Menu"
+ {
+ Title
+ {
+ @Menu
+ }
+ }
+
+ Decor = "WorkspaceIndicator"
+ {
+ Title
+ {
+ @Workspace
+ }
+ }
+
+ Decor = "Titlebarless"
+ {
+ Title
+ {
+ @Empty
+ }
+ }
+
+ Decor = "Statuswindow"
+ {
+ Title
+ {
+ @Empty
+ }
+ }
+
+ Decor = "CmdDialog"
+ {
+ Title
+ {
+ @Base
+ }
+ }
+}
+
+Harbour
+{
+ Texture = "Solid #dcddcf"
+}
+
+Menu
+{
+ Pad = "0 0 0 0"
+ Focused
+ {
+ Font = "$font"
+ Background = "Solid #FBFBFB"
+# Item = "Empty"
+ Text = "#696969"
+ Separator = "Image menuline.png#scaled"
+ Arrow = "Image arrow.png#scaled"
+ }
+ Unfocused
+ {
+ Font = "$font"
+ Background = "Solid #FBFBFB"
+# Item = "Empty"
+ Text = "#696969"
+ Separator = "Image menuline.png#scaled"
+ Arrow = "Image arrow.png#scaled"
+ }
+ Selected
+ {
+ Font = "$font"
+ Background = "Solid #FBFBFB"
+ Item = "Empty"
+ Text = "#79A9F7"
+ Arrow = "Image arrow.png#scaled"
+ }
+}
+
+CmdDialog
+{
+ Font = "$font"
+ Texture = "Solid #FBFBFB"
+ Text = "#696969"
+# Pad = "2 2 2 2"
+}
+
+Status
+{
+ Font = "$font"
+ Texture = "Solid #FBFBFB"
+ Text = "#696969"
+# Pad = "2 2 10 10"
+}
+WorkspaceIndicator
+{
+ Font = "$font"
+ Background = "Solid #FBFBFB"
+ Workspace = "Solid #878787"
+ WorkspaceActive = "Solid #79A9F7"
+ Text = "#878787"
+ EdgePadding = "10"
+ WorkspacePadding= "20"
+}
+
blob - /dev/null
blob + 1c66543a86c385d51b5de3c3d13936fec222f9b0 (mode 644)
Binary files /dev/null and themes/My_minimalist/title.png differ
blob - /dev/null
blob + 0602b654a10bdc86fc00da439f33082932afbc31 (mode 644)
Binary files /dev/null and themes/My_minimalist/top.png differ
blob - /dev/null
blob + 41fa33a57136250bc7d3877ee02e46c7cf0e5eb6 (mode 644)
--- /dev/null
+++ vars
+# This file is in the public domain. Anyone is free to copy, modify, publish
+# use, sell or distribute for any purpose, commercial or non-commercial, and by
+# any means.
+
+$BROWSER="firefox"
+$EDITOR="alacritty -e nvim"
+$FILEMANAGER="spacefm"
+$EMAILS="thunderbird"
+#$TERM="xterm -fn fixed +sb -bg white -fg black"
+$TERM="alacritty --class grouped"
+
+# Used in MoveResize section of keys, change to make keyboard driven move and
+# resize increments change.
+$MOVERESIZE_INCREMENT="15"