diff --git a/configuration.nix b/configuration.nix index 9ef3cdb..3a82108 100644 --- a/configuration.nix +++ b/configuration.nix @@ -130,37 +130,50 @@ "wireshark" ]; shell = pkgs.nushell; - packages = with pkgs; [ - tree - dust - eza - wl-clipboard - ripgrep - fd - keepassxc - btop - fluffychat - cargo - rustc - upx - gcc - nixfmt - imv - unzip - zip - qbittorrent - typst - calibre - signal-desktop - rustfmt - wmenu - umu-launcher - cachix - grim - slurp - wireshark - brightnessctl - ]; + packages = + with pkgs; + let + wmenu = + (pkgs.wmenu.override { + }).overrideAttrs + (oldAttrs: { + patches = oldAttrs.patches or [ ] ++ [ + ./wmenu/desktop.patch + ]; + buildInputs = oldAttrs.buildInputs ++ [ glib ]; + }); + in + [ + tree + dust + eza + wl-clipboard + ripgrep + fd + keepassxc + btop + fluffychat + cargo + rustc + upx + gcc + nixfmt + imv + unzip + zip + qbittorrent + typst + calibre + signal-desktop + rustfmt + wmenu + umu-launcher + cachix + grim + slurp + wireshark + brightnessctl + ]; }; security.doas = { @@ -189,23 +202,29 @@ configH = ./dwl/config.h; enableXWayland = false; }).overrideAttrs - (oldAttrs: { - version = "0.8"; - src = pkgs.fetchFromCodeberg { - owner = "dwl"; - repo = "dwl"; - rev = "v0.8"; - hash = "sha256-J76L5ZOCYgfcY08wH5cSLG+UdgDrv50lQyEnJNqDkXI="; - }; - buildInputs = lib.lists.remove pkgs.wlroots_0_18 oldAttrs.buildInputs ++ [ - pkgs.libdrm - pkgs.fcft - pkgs.wlroots_0_19 - ]; - patches = oldAttrs.patches or [ ] ++ [ - ./dwl/patches/bar.patch - ]; - }); + ( + oldAttrs: + let + version = "0.8"; + in + { + inherit version; + src = pkgs.fetchFromCodeberg { + owner = "dwl"; + repo = "dwl"; + rev = "v${version}"; + hash = "sha256-J76L5ZOCYgfcY08wH5cSLG+UdgDrv50lQyEnJNqDkXI="; + }; + buildInputs = lib.lists.remove pkgs.wlroots_0_18 oldAttrs.buildInputs ++ [ + pkgs.libdrm + pkgs.fcft + pkgs.wlroots_0_19 + ]; + patches = oldAttrs.patches or [ ] ++ [ + ./dwl/patches/bar.patch + ]; + } + ); }; # For more information, see `man configuration.nix` or https://nixos.org/manual/nixos/stable/options#opt-system.stateVersion . diff --git a/dwl/config.h b/dwl/config.h index f9944b1..1f8a56f 100644 --- a/dwl/config.h +++ b/dwl/config.h @@ -9,7 +9,7 @@ static const int bypass_surface_visibility = 0; /* 1 means idle inhibitors will static const unsigned int borderpx = 1; /* border pixel of windows */ static const int showbar = 1; /* 0 means no bar */ static const int topbar = 1; /* 0 means bottom bar */ -static const char *fonts[] = {"monospace:size=10"}; +static const char *fonts[] = {"Hack:size=10"}; static const float rootcolor[] = COLOR(0x000000ff); /* This conforms to the xdg-protocol. Set the alpha to zero to restore the old behavior */ static const float fullscreen_bg[] = {0.0f, 0.0f, 0.0f, 1.0f}; /* You can also use glsl colors */ @@ -49,6 +49,7 @@ static const MonitorRule monrules[] = { /* name mfact nmaster scale layout rotate/reflect x y * example of a HiDPI laptop monitor: { "eDP-1", 0.5f, 1, 2, &layouts[0], WL_OUTPUT_TRANSFORM_NORMAL, -1, -1 }, */ + { "eDP-1", 0.5f, 1, 2, &layouts[0], WL_OUTPUT_TRANSFORM_NORMAL, -1, -1 }, { NULL, 0.55f, 1, 1, &layouts[0], WL_OUTPUT_TRANSFORM_NORMAL, -1, -1 }, /* default monitor rule: can be changed but cannot be eliminated; at least one monitor rule must exist */ }; @@ -59,6 +60,7 @@ static const struct xkb_rule_names xkb_rules = { /* example: .options = "ctrl:nocaps", */ + .layout = "no", .options = NULL, }; @@ -99,7 +101,7 @@ static const uint32_t send_events_mode = LIBINPUT_CONFIG_SEND_EVENTS_ENABLED; LIBINPUT_CONFIG_ACCEL_PROFILE_FLAT LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE */ -static const enum libinput_config_accel_profile accel_profile = LIBINPUT_CONFIG_ACCEL_PROFILE_FLAT; +static const enum libinput_config_accel_profile accel_profile = LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE; static const double accel_speed = 0.0; /* You can choose between: @@ -121,14 +123,31 @@ static const enum libinput_config_tap_button_map button_map = LIBINPUT_CONFIG_TA #define SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } } /* commands */ -static const char *termcmd[] = { "foot", NULL }; -static const char *menucmd[] = { "wmenu-run", NULL }; +static const char *termcmd[] = { "foot", NULL }; +static const char *menucmd[] = { "wmenu-drun", "-i", "-f", "Hack 9", NULL }; +static const char *loudcmd[] = { "wpctl", "set-volume", "@DEFAULT_AUDIO_SINK@", "1%+", NULL }; +static const char *quietcmd[] = { "wpctl", "set-volume", "@DEFAULT_AUDIO_SINK@", "1%-", NULL }; +static const char *silencecmd[] = { "wpctl", "set-mute", "@DEFAULT_AUDIO_SINK@", "toggle", NULL }; +static const char *mutecmd[] = { "wpctl", "set-mute", "@DEFAULT_AUDIO_SOURCE@", "toggle", NULL }; +static const char *brightcmd[] = { "brightnessctl", "set", "+5%", NULL }; +static const char *dimcmd[] = { "brightnessctl", "set", "5%-", NULL }; +static const char *shutdowncmd[] = { "shutdown", "now", NULL }; + static const Key keys[] = { /* Note that Shift changes certain key codes: 2 -> at, etc. */ /* modifier key function argument */ { MODKEY, XKB_KEY_p, spawn, {.v = menucmd} }, { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_Return, spawn, {.v = termcmd} }, + /* custom */ + /* modifier key function argument */ + { 0, XKB_KEY_XF86AudioRaiseVolume, spawn, {.v = loudcmd} }, + { 0, XKB_KEY_XF86AudioLowerVolume, spawn, {.v = quietcmd} }, + { 0, XKB_KEY_XF86AudioMute, spawn, {.v = silencecmd} }, + { 0, XKB_KEY_XF86AudioMicMute, spawn, {.v = mutecmd} }, + { 0, XKB_KEY_XF86MonBrightnessUp, spawn, {.v = brightcmd} }, + { 0, XKB_KEY_XF86MonBrightnessDown, spawn, {.v = dimcmd} }, + /* custom */ { MODKEY, XKB_KEY_b, togglebar, {0} }, { MODKEY, XKB_KEY_j, focusstack, {.i = +1} }, { MODKEY, XKB_KEY_k, focusstack, {.i = -1} }, diff --git a/home/home.nix b/home/home.nix index e177316..2a93df0 100644 --- a/home/home.nix +++ b/home/home.nix @@ -232,6 +232,7 @@ set-option -g focus-events on set-option -sg escape-time 10 set -g mouse on + set-option -g status-position top ''; }; } diff --git a/wmenu/desktop.patch b/wmenu/desktop.patch new file mode 100644 index 0000000..2c9c8a9 --- /dev/null +++ b/wmenu/desktop.patch @@ -0,0 +1,251 @@ +File wmenu/.git is a directory while file wmenud/.git is a regular file +diff -Nur wmenu/menu.c wmenud/menu.c +--- wmenu/menu.c 2026-03-31 04:31:08.735754566 +0200 ++++ wmenud/menu.c 2026-03-31 04:31:00.976768869 +0200 +@@ -172,7 +172,7 @@ + } + + // Add an item to the menu. +-void menu_add_item(struct menu *menu, char *text) { ++void menu_add_item(struct menu *menu, char *text, void *app_info) { + if ((menu->item_count & (menu->item_count - 1)) == 0) { + size_t alloc_size = menu->item_count ? 2 * menu->item_count : 1; + void *new_array = realloc(menu->items, sizeof(struct item) * alloc_size); +@@ -185,6 +185,7 @@ + + struct item *new = &menu->items[menu->item_count]; + new->text = text; ++ new->app_info = app_info; + + menu->item_count++; + } +@@ -593,10 +594,10 @@ + case XKB_KEY_Return: + case XKB_KEY_KP_Enter: + if (shift) { +- menu->callback(menu, menu->input, true); ++ menu->callback(menu, menu->input, menu->sel->app_info, true); + } else { + char *text = menu->sel ? menu->sel->text : menu->input; +- menu->callback(menu, text, !ctrl); ++ menu->callback(menu, text, menu->sel->app_info, !ctrl); + } + break; + case XKB_KEY_Left: +diff -Nur wmenu/menu.h wmenud/menu.h +--- wmenu/menu.h 2026-03-31 04:31:08.735754566 +0200 ++++ wmenud/menu.h 2026-03-31 04:31:00.976768869 +0200 +@@ -6,13 +6,15 @@ + #include + #include + #include ++#include + + struct menu; +-typedef void (*menu_callback)(struct menu *menu, char *text, bool exit); ++typedef void (*menu_callback)(struct menu *menu, char *text, GAppInfo *app_info, bool exit); + + // A menu item. + struct item { + char *text; ++ GAppInfo *app_info; + int width; + struct item *prev_match; // previous matching item + struct item *next_match; // next matching item +@@ -84,7 +86,7 @@ + struct menu *menu_create(menu_callback callback); + void menu_destroy(struct menu *menu); + void menu_getopts(struct menu *menu, int argc, char *argv[]); +-void menu_add_item(struct menu *menu, char *text); ++void menu_add_item(struct menu *menu, char *text, void *app_info); + void menu_sort_and_deduplicate(struct menu *menu); + void menu_calc_height(struct menu *menu); + void menu_invalidate(struct menu *menu); +diff -Nur wmenu/meson.build wmenud/meson.build +--- wmenu/meson.build 2026-03-31 04:31:08.735754566 +0200 ++++ wmenud/meson.build 2026-03-31 04:31:00.976768869 +0200 +@@ -7,6 +7,7 @@ + 'c_std=c11', + 'warning_level=2', + 'werror=true', ++ 'optimization=3', + ] + ) + +@@ -19,6 +20,7 @@ + '-Wno-unused-parameter', + '-Wundef', + '-Wvla', ++ '-Wno-discarded-qualifiers', + ]), language : 'c') + + cairo = dependency('cairo') +@@ -27,6 +29,8 @@ + wayland_client = dependency('wayland-client') + wayland_protos = dependency('wayland-protocols') + xkbcommon = dependency('xkbcommon') ++glib = dependency('glib-2.0') ++gio_unix = dependency('gio-unix-2.0') + + rt = cc.find_library('rt') + +@@ -78,3 +82,28 @@ + ], + install: true, + ) ++ ++executable( ++ 'wmenu-drun', ++ files( ++ 'menu.c', ++ 'pango.c', ++ 'pool-buffer.c', ++ 'render.c', ++ 'wayland.c', ++ 'wmenu-drun.c', ++ ), ++ dependencies: [ ++ cairo, ++ client_protos, ++ pango, ++ pangocairo, ++ rt, ++ wayland_client, ++ wayland_protos, ++ xkbcommon, ++ glib, ++ gio_unix, ++ ], ++ install: true, ++) +diff -Nur wmenu/wmenu.c wmenud/wmenu.c +--- wmenu/wmenu.c 2026-03-31 04:31:08.736754564 +0200 ++++ wmenud/wmenu.c 2026-03-31 04:31:00.979768864 +0200 +@@ -2,6 +2,7 @@ + + #include + #include ++#include + + #include "menu.h" + #include "wayland.h" +@@ -13,11 +14,11 @@ + if (p) { + *p = '\0'; + } +- menu_add_item(menu, strdup(buf)); ++ menu_add_item(menu, strdup(buf), NULL); + } + } + +-static void print_item(struct menu *menu, char *text, bool exit) { ++static void print_item(struct menu *menu, char *text, GAppInfo *app_info, bool exit) { + puts(text); + fflush(stdout); + if (exit) { +diff -Nur wmenu/wmenu-drun.c wmenud/wmenu-drun.c +--- wmenu/wmenu-drun.c 1970-01-01 01:00:00.000000000 +0100 ++++ wmenud/wmenu-drun.c 2026-03-31 21:24:43.667365628 +0200 +@@ -0,0 +1,73 @@ ++#define _POSIX_C_SOURCE 200809L ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "menu.h" ++#include "wayland.h" ++#include "xdg-activation-v1-client-protocol.h" ++ ++static void read_items(struct menu *menu) { ++ GList* list = g_app_info_get_all(); ++ GList* item; ++ for(item = list; item; item = item->next) { ++ if (g_app_info_should_show(item->data) == FALSE) { ++ continue; ++ } ++ const char *name = g_app_info_get_name(item->data); ++ menu_add_item(menu, name, item->data); ++ } ++ menu_sort_and_deduplicate(menu); ++} ++ ++struct command { ++ struct menu *menu; ++ char *text; ++ GAppInfo *app_info; ++ bool exit; ++}; ++ ++static void activation_token_done(void *data, struct xdg_activation_token_v1 *activation_token, ++ const char *token) { ++ struct command *cmd = data; ++ xdg_activation_token_v1_destroy(activation_token); ++ ++ GAppLaunchContext *context = g_app_launch_context_new(); // Not strictly necessary. ++ g_app_info_launch(cmd->app_info, NULL, context, NULL); ++ setenv("XDG_ACTIVATION_TOKEN", token, true); ++ xdg_activation_token_v1_destroy(activation_token); ++ cmd->menu->exit = true; ++} ++ ++static const struct xdg_activation_token_v1_listener activation_token_listener = { ++ .done = activation_token_done, ++}; ++ ++static void exec_item(struct menu *menu, char *text, GAppInfo *app_info, bool exit) { ++ struct command *cmd = calloc(1, sizeof(struct command)); ++ cmd->menu = menu; ++ cmd->text = strdup(text); ++ cmd->app_info = app_info; ++ if (cmd->app_info == NULL) { ++ printf("app info is nil\n"); ++ } ++ cmd->exit = exit; ++ ++ struct xdg_activation_v1 *activation = context_get_xdg_activation(menu->context); ++ struct xdg_activation_token_v1 *activation_token = xdg_activation_v1_get_activation_token(activation); ++ xdg_activation_token_v1_set_surface(activation_token, context_get_surface(menu->context)); ++ xdg_activation_token_v1_add_listener(activation_token, &activation_token_listener, cmd); ++ xdg_activation_token_v1_commit(activation_token); ++} ++ ++int main(int argc, char *argv[]) { ++ struct menu *menu = menu_create(exec_item); ++ menu_getopts(menu, argc, argv); ++ read_items(menu); ++ int status = menu_run(menu); ++ menu_destroy(menu); ++ return status; ++} +diff -Nur wmenu/wmenu-run.c wmenud/wmenu-run.c +--- wmenu/wmenu-run.c 2026-03-31 04:31:08.735754566 +0200 ++++ wmenud/wmenu-run.c 2026-03-31 04:31:00.979768864 +0200 +@@ -4,6 +4,7 @@ + #include + #include + #include ++#include + + #include "menu.h" + #include "wayland.h" +@@ -20,7 +21,7 @@ + if (ent->d_name[0] == '.') { + continue; + } +- menu_add_item(menu, strdup(ent->d_name)); ++ menu_add_item(menu, strdup(ent->d_name), NULL); + } + closedir(dir); + } +@@ -55,7 +56,7 @@ + .done = activation_token_done, + }; + +-static void exec_item(struct menu *menu, char *text, bool exit) { ++static void exec_item(struct menu *menu, char *text, GAppInfo *app_info, bool exit) { + struct command *cmd = calloc(1, sizeof(struct command)); + cmd->menu = menu; + cmd->text = strdup(text);