diff options
| author | Mitja Felicijan <mitja.felicijan@gmail.com> | 2026-04-15 18:51:07 +0200 |
|---|---|---|
| committer | Mitja Felicijan <mitja.felicijan@gmail.com> | 2026-04-15 18:51:07 +0200 |
| commit | 9b0d35aa6c6fb995f6a15906a43fd50b3a58f822 (patch) | |
| tree | 33be21d5fccdf73a499751ccf6944bf53c8e9398 | |
| parent | 55f211a5a5217f67abec6dee50b1d7052bf28b59 (diff) | |
| download | glitch-9b0d35aa6c6fb995f6a15906a43fd50b3a58f822.tar.gz | |
Merge in sorting of launcher items with glib functions
| -rw-r--r-- | README.md | 10 | ||||
| -rw-r--r-- | glitch.h | 1 | ||||
| -rw-r--r-- | launcher.c | 53 |
3 files changed, 61 insertions, 3 deletions
@@ -18,6 +18,7 @@ Glitch is a minimal X11 window manager controlled by keyboard shortcuts. - **Window Centering**: Center windows on screen - **Audio Control**: Toggle microphone mute with on-screen status - **Tiling Layout**: Toggle between floating and tiling layouts per desktop +- **Application Launcher**: Integrated .desktop-aware launcher with usage-based sorting - **On-screen Indicators**: Live status for desktop, layout, mic, and clock - **Live Reload**: Reload configuration without restart @@ -26,6 +27,8 @@ Glitch is a minimal X11 window manager controlled by keyboard shortcuts. - Built on X11/Xlib for low-level window management - Uses EWMH (Extended Window Manager Hints) for fullscreen and state functionality - Integrated PulseAudio support for real-time microphone status tracking +- Uses GIO/GLib for standard-compliant .desktop file parsing and application discovery +- Persistent usage tracking for applications to provide "most used" sorting - Xft-based on-screen widgets for system status (Clock, Mic, Layout, Desktop) - Maintains state for maximized windows to enable toggle behavior - Implements proper X11 event handling and window attribute management @@ -38,13 +41,14 @@ Glitch is a minimal X11 window manager controlled by keyboard shortcuts. - X11 and Freetype development libraries - libXft development library - PulseAudio development library +- GLib/GIO development libraries ### Installing Dependencies **Void Linux:** ```sh -sudo xbps-install libX11-devel freetype-devel libXft-devel pulseaudio-devel pkg-config +sudo xbps-install libX11-devel freetype-devel libXft-devel pulseaudio-devel glib-devel pkg-config ``` ## Compilation @@ -182,6 +186,7 @@ Modifier key: `Mod4` (Super/Windows key) { MODKEY, XK_f, toggle_fullscreen, { 0 } }, { MODKEY, XK_q, close_window, { 0 } }, { MODKEY, XK_m, toggle_mic_mute, { 0 } }, +{ MODKEY, XK_p, toggle_launcher, { 0 } }, { MODKEY, XK_space, toggle_layout, { 0 } }, { MODKEY | ShiftMask, XK_q, quit, { 0 } }, { MODKEY | ShiftMask, XK_r, reload, { 0 } }, @@ -211,7 +216,7 @@ Modifier key: `Mod4` (Super/Windows key) Defined in `shortcuts[]` array: - `Mod+Return`: Terminal (st) -- `Mod+p`: Application launcher (rofi) +- `Mod+p`: Internal application launcher - `Mod+w`: Browser (brave) - `Mod+e`: File Manager (thunar) - `Mod+s`: Screen magnifier (xmagnify) @@ -243,5 +248,6 @@ Defined in `shortcuts[]` array: | `window_hmaximize` | Maximize | None | Toggle horizontal maximize | | `window_vmaximize` | Maximize | None | Toggle vertical maximize | | `toggle_mic_mute` | Audio | None | Toggle microphone mute state | +| `toggle_launcher` | Control | None | Toggle integrated app launcher | | `toggle_layout` | Layout | None | Toggle between floating/tiling | | `reload` | System | None | Reload configuration/restart WM | @@ -58,6 +58,7 @@ typedef struct Client { typedef struct { char *name; char *exec; + int usage; } LauncherItem; typedef struct { @@ -10,6 +10,7 @@ #include <X11/Xutil.h> #include <X11/keysym.h> +#include <sys/stat.h> #include <gio/gio.h> #include "glitch.h" @@ -19,6 +20,47 @@ extern WindowManager wm; static void launcher_filter(void); +static int compare_launcher_items(const void *a, const void *b) { + const LauncherItem *ia = (const LauncherItem *)a; + const LauncherItem *ib = (const LauncherItem *)b; + if (ib->usage != ia->usage) + return ib->usage - ia->usage; + return strcasecmp(ia->name, ib->name); +} + +static void load_usage(void) { + char path[1024]; + char *home = getenv("HOME"); + if (!home) return; + snprintf(path, sizeof(path), "%s/.cache/glitch/usage.db", home); + + GKeyFile *kf = g_key_file_new(); + if (g_key_file_load_from_file(kf, path, G_KEY_FILE_NONE, NULL)) { + for (int i = 0; i < wm.launcher_items_count; i++) { + wm.launcher_items[i].usage = g_key_file_get_integer(kf, "Usage", wm.launcher_items[i].exec, NULL); + } + } + g_key_file_free(kf); +} + +static void record_usage(const char *exec) { + char path[1024]; + char *home = getenv("HOME"); + if (!home) return; + snprintf(path, sizeof(path), "%s/.cache/glitch", home); + mkdir(path, 0755); + snprintf(path, sizeof(path), "%s/.cache/glitch/usage.db", home); + + GKeyFile *kf = g_key_file_new(); + g_key_file_load_from_file(kf, path, G_KEY_FILE_NONE, NULL); + + int count = g_key_file_get_integer(kf, "Usage", exec, NULL); + g_key_file_set_integer(kf, "Usage", exec, count + 1); + + g_key_file_save_to_file(kf, path, NULL); + g_key_file_free(kf); +} + static void load_applications(void) { if (wm.launcher_items) { for (int i = 0; i < wm.launcher_items_count; i++) { @@ -47,8 +89,10 @@ static void load_applications(void) { if (name && exec) { wm.launcher_items[wm.launcher_items_count].name = strdup(name); + wm.launcher_items[wm.launcher_items_count].usage = 0; char *e = strdup(exec); + char *percent = strchr(e, '%'); if (percent) *percent = '\0'; @@ -66,6 +110,9 @@ static void load_applications(void) { g_object_unref(app); } g_list_free(apps); + + load_usage(); + qsort(wm.launcher_items, wm.launcher_items_count, sizeof(LauncherItem), compare_launcher_items); } void toggle_launcher(const Arg *arg) { @@ -77,7 +124,10 @@ void toggle_launcher(const Arg *arg) { return; } - if (!wm.launcher_items) { + if (wm.launcher_items) { + load_usage(); + qsort(wm.launcher_items, wm.launcher_items_count, sizeof(LauncherItem), compare_launcher_items); + } else { load_applications(); } @@ -143,6 +193,7 @@ void launcher_handle_key(void) { } } else if (keysym == XK_Return) { if (wm.launcher_filtered_count > 0 && wm.launcher_selected < wm.launcher_filtered_count) { + record_usage(wm.launcher_filtered[wm.launcher_selected]->exec); execute_shortcut(wm.launcher_filtered[wm.launcher_selected]->exec); toggle_launcher(NULL); return; |
