diff --git a/profiles/work/home.nix b/profiles/work/home.nix index 031cc3c..271e111 100644 --- a/profiles/work/home.nix +++ b/profiles/work/home.nix @@ -231,4 +231,6 @@ name = if (config.stylix.polarity == "dark") then "Papirus-Dark" else "Papirus-Light"; }; + services.pasystray.enable = true; + } diff --git a/user/wm/hyprland/hyprland.nix b/user/wm/hyprland/hyprland.nix index c7817f1..e896110 100644 --- a/user/wm/hyprland/hyprland.nix +++ b/user/wm/hyprland/hyprland.nix @@ -45,6 +45,7 @@ in env = QT_AUTO_SCREEN_SCALE_FACTOR,1 env = QT_WAYLAND_DISABLE_WINDOWDECORATION,1 env = CLUTTER_BACKEND,wayland + env = GDK_PIXBUF_MODULE_FILE,${pkgs.librsvg}/lib/gdk-pixbuf-2.0/2.10.0/loaders.cache exec-once = hyprprofile Default @@ -459,7 +460,6 @@ in hypridle hyprpaper fnott - fuzzel keepmenu pinentry-gnome3 wev @@ -759,6 +759,7 @@ in sed -i 's/zext_workspace_handle_v1_activate(workspace_handle_);/const std::string command = "hyprctl dispatch focusworkspaceoncurrentmonitor " + std::to_string(id());\n\tsystem(command.c_str());/g' src/modules/wlr/workspace_manager.cpp sed -i 's/gIPC->getSocket1Reply("dispatch workspace " + std::to_string(id()));/gIPC->getSocket1Reply("dispatch focusworkspaceoncurrentmonitor " + std::to_string(id()));/g' src/modules/hyprland/workspaces.cpp ''; + patches = [./patches/waybarpaupdate.patch ./patches/waybarbatupdate.patch]; }); settings = { mainBar = { @@ -768,28 +769,70 @@ in margin = "7 7 3 7"; spacing = 2; - modules-left = [ "custom/os" "custom/hyprprofile" "battery" "backlight" "keyboard-state" "pulseaudio" "cpu" "memory" ]; - modules-center = [ "hyprland/workspaces" ]; - modules-right = [ "idle_inhibitor" "tray" "clock" ]; + modules-left = [ "group/power" "group/battery" "group/backlight" "group/cpu" "group/memory" "group/pulseaudio" "keyboard-state" ]; + modules-center = [ "custom/hyprprofile" "hyprland/workspaces" ]; + modules-right = [ "group/time" "idle_inhibitor" "tray" ]; "custom/os" = { "format" = " {} "; "exec" = ''echo "" ''; "interval" = "once"; "on-click" = "nwggrid-wrapper"; + "tooltip" = false; + }; + "group/power" = { + "orientation" = "horizontal"; + "drawer" = { + "transition-duration" = 500; + "children-class" = "not-power"; + "transition-left-to-right" = true; + }; + "modules" = [ + "custom/os" + "custom/hyprprofileicon" + "custom/lock" + "custom/quit" + "custom/power" + "custom/reboot" + ]; + }; + "custom/quit" = { + "format" = "󰍃"; + "tooltip" = false; + "on-click" = "hyprctl dispatch exit"; + }; + "custom/lock" = { + "format" = "󰍁"; + "tooltip" = false; + "on-click" = "hyprlock"; + }; + "custom/reboot" = { + "format" = "󰜉"; + "tooltip" = false; + "on-click" = "reboot now"; + }; + "custom/power" = { + "format" = "󰐥"; + "tooltip" = false; + "on-click" = "shutdown now"; + }; + "custom/hyprprofileicon" = { + "format" = "󱙋"; + "on-click" = "hyprprofile-dmenu"; + "tooltip" = false; }; "custom/hyprprofile" = { - "format" = "  {}"; + "format" = " {}"; "exec" = ''cat ~/.hyprprofile''; "interval" = 3; "on-click" = "hyprprofile-dmenu"; }; "keyboard-state" = { "numlock" = true; - "format" = " {icon} "; + "format" = "{icon}"; "format-icons" = { - "locked" = "󰎠"; - "unlocked" = "󱧓"; + "locked" = "󰎠 "; + "unlocked" = "󱧓 "; }; }; "hyprland/workspaces" = { @@ -813,25 +856,10 @@ in "on-click" = "activate"; "on-scroll-up" = "hyprctl dispatch workspace e+1"; "on-scroll-down" = "hyprctl dispatch workspace e-1"; - #"all-outputs" = true; - #"active-only" = true; + "all-outputs" = false; + "active-only" = false; "ignore-workspaces" = ["scratch" "-"]; - #"show-special" = false; - #"persistent-workspaces" = { - # # this block doesn't seem to work for whatever reason - # "eDP-1" = [1 2 3 4 5 6 7 8 9]; - # "DP-1" = [1 2 3 4 5 6 7 8 9]; - # "HDMI-A-1" = [1 2 3 4 5 6 7 8 9]; - # "1" = ["eDP-1" "DP-1" "HDMI-A-1"]; - # "2" = ["eDP-1" "DP-1" "HDMI-A-1"]; - # "3" = ["eDP-1" "DP-1" "HDMI-A-1"]; - # "4" = ["eDP-1" "DP-1" "HDMI-A-1"]; - # "5" = ["eDP-1" "DP-1" "HDMI-A-1"]; - # "6" = ["eDP-1" "DP-1" "HDMI-A-1"]; - # "7" = ["eDP-1" "DP-1" "HDMI-A-1"]; - # "8" = ["eDP-1" "DP-1" "HDMI-A-1"]; - # "9" = ["eDP-1" "DP-1" "HDMI-A-1"]; - #}; + "show-special" = false; }; "idle_inhibitor" = { @@ -845,43 +873,106 @@ in #"icon-size" = 21; "spacing" = 10; }; - clock = { + "clock#time" = { "interval" = 1; - "format" = "{:%a %Y-%m-%d %I:%M:%S %p}"; + "format" = "{:%I:%M:%S %p}"; "timezone" = "America/Chicago"; "tooltip-format" = '' {:%Y %B} {calendar}''; }; - cpu = { - "format" = "{usage}% "; + "clock#date" = { + "interval" = 1; + "format" = "{:%a %Y-%m-%d}"; + "timezone" = "America/Chicago"; + "tooltip-format" = '' + {:%Y %B} + {calendar}''; }; - memory = { "format" = "{}% "; }; + "group/time" = { + "orientation" = "horizontal"; + "drawer" = { + "transition-duration" = 500; + "transition-left-to-right" = false; + }; + "modules" = [ "clock#time" "clock#date" ]; + }; + + cpu = { "format" = "󰍛"; }; + "cpu#text" = { "format" = "{usage}%"; }; + "group/cpu" = { + "orientation" = "horizontal"; + "drawer" = { + "transition-duration" = 500; + "transition-left-to-right" = true; + }; + "modules" = [ "cpu" "cpu#text" ]; + }; + + memory = { "format" = ""; }; + "memory#text" = { "format" = "{}%"; }; + "group/memory" = { + "orientation" = "horizontal"; + "drawer" = { + "transition-duration" = 500; + "transition-left-to-right" = true; + }; + "modules" = [ "memory" "memory#text" ]; + }; + backlight = { - "format" = "{percent}% {icon}"; + "format" = "{icon}"; "format-icons" = [ "" "" "" "" "" "" "" "" "" ]; }; + "backlight#text" = { "format" = "{percent}%"; }; + "group/backlight" = { + "orientation" = "horizontal"; + "drawer" = { + "transition-duration" = 500; + "transition-left-to-right" = true; + }; + "modules" = [ "backlight" "backlight#text" ]; + }; + battery = { "states" = { - "good" = 95; + "good" = 75; "warning" = 30; "critical" = 15; }; - "format" = "{capacity}% {icon}"; - "format-charging" = "{capacity}% "; - "format-plugged" = "{capacity}% "; - #"format-good" = ""; # An empty format will hide the module - #"format-full" = ""; - "format-icons" = [ "" "" "" "" "" ]; + "fullat" = 80; + "format" = "{icon}"; + "format-charging" = "󰂄"; + "format-plugged" = "󰂄"; + "format-full" = "󰁹"; + "format-icons" = [ "󰁺" "󰁻" "󰁼" "󰁽" "󰁾" "󰁿" "󰂀" "󰂁" "󰂂" "󰁹" ]; + "interval" = 10; + }; + "battery#text" = { + "states" = { + "good" = 75; + "warning" = 30; + "critical" = 15; + }; + "fullat" = 80; + "format" = "{capacity}%"; + }; + "group/battery" = { + "orientation" = "horizontal"; + "drawer" = { + "transition-duration" = 500; + "transition-left-to-right" = true; + }; + "modules" = [ "battery" "battery#text" ]; }; pulseaudio = { "scroll-step" = 1; - "format" = "{volume}% {icon} {format_source}"; - "format-bluetooth" = "{volume}% {icon}  {format_source}"; - "format-bluetooth-muted" = "󰸈 {icon}  {format_source}"; - "format-muted" = "󰸈 {format_source}"; - "format-source" = "{volume}% "; - "format-source-muted" = " "; + "format" = "{icon}"; + "format-bluetooth" = "{icon}"; + "format-bluetooth-muted" = "󰸈"; + "format-muted" = "󰸈"; + "format-source" = ""; + "format-source-muted" = ""; "format-icons" = { "headphone" = ""; "hands-free" = ""; @@ -893,6 +984,24 @@ in }; "on-click" = "pypr toggle pavucontrol && hyprctl dispatch bringactivetotop"; }; + "pulseaudio#text" = { + "scroll-step" = 1; + "format" = "{volume}%"; + "format-bluetooth" = "{volume}%"; + "format-bluetooth-muted" = ""; + "format-muted" = ""; + "format-source" = "{volume}%"; + "format-source-muted" = ""; + "on-click" = "pypr toggle pavucontrol && hyprctl dispatch bringactivetotop"; + }; + "group/pulseaudio" = { + "orientation" = "horizontal"; + "drawer" = { + "transition-duration" = 500; + "transition-left-to-right" = true; + }; + "modules" = [ "pulseaudio" "pulseaudio#text" ]; + }; }; }; style = '' @@ -948,7 +1057,7 @@ in } #workspaces button { - padding: 0 7px; + padding: 0px 6px; background-color: transparent; color: #'' + config.lib.stylix.colors.base04 + ''; } @@ -973,7 +1082,6 @@ in color: #'' + config.lib.stylix.colors.base09 + ''; } - #clock, #battery, #cpu, #memory, @@ -988,16 +1096,44 @@ in #mode, #idle_inhibitor, #scratchpad, + #custom-hyprprofileicon, + #custom-quit, + #custom-lock, + #custom-reboot, + #custom-power, #mpd { - padding: 0 10px; + padding: 0 3px; color: #'' + config.lib.stylix.colors.base07 + ''; border: none; border-radius: 8px; } + #custom-hyprprofileicon, + #custom-quit, + #custom-lock, + #custom-reboot, + #custom-power, + #idle_inhibitor { + background-color: transparent; + color: #'' + config.lib.stylix.colors.base04 + ''; + } + + #custom-hyprprofileicon:hover, + #custom-quit:hover, + #custom-lock:hover, + #custom-reboot:hover, + #custom-power:hover, + #idle_inhibitor:hover { + color: #'' + config.lib.stylix.colors.base07 + ''; + } + + #clock, #tray, #idle_inhibitor { + padding: 0 5px; + } + #window, #workspaces { - margin: 0 4px; + margin: 0 6px; } /* If workspaces is the leftmost module, omit left margin */ @@ -1208,6 +1344,9 @@ in services.udiskie.enable = true; services.udiskie.tray = "always"; programs.fuzzel.enable = true; + programs.fuzzel.package = pkgs.fuzzel.overrideAttrs (oldAttrs: { + patches = ./patches/fuzzelmouseinput.patch; + }); programs.fuzzel.settings = { main = { font = userSettings.font + ":size=20"; diff --git a/user/wm/hyprland/patches/fuzzelmouseinput.patch b/user/wm/hyprland/patches/fuzzelmouseinput.patch new file mode 100644 index 0000000..0264ac1 --- /dev/null +++ b/user/wm/hyprland/patches/fuzzelmouseinput.patch @@ -0,0 +1,1053 @@ +From 7cc9f3147438fe7dd0062172f46aed415f024464 Mon Sep 17 00:00:00 2001 +From: alz +Date: Mon, 22 Jul 2024 00:43:56 -0400 +Subject: [PATCH 1/7] implemented left click, right click and scroll wheel + listeners + +--- + match.c | 24 ++++++++++++++++++++++++ + match.h | 1 + + render.c | 19 +++++++++++++++++++ + render.h | 2 ++ + wayland.c | 38 ++++++++++++++++++++++++++++++++++++++ + 5 files changed, 84 insertions(+) + +diff --git a/match.c b/match.c +index 5a26000..7d5efaf 100644 +--- a/match.c ++++ b/match.c +@@ -359,6 +359,30 @@ matches_selected_select(struct matches *matches, const char *_string) + return false; + } + ++bool ++matches_selected_select_idx(struct matches *matches, size_t idx) ++{ ++ const size_t page_no = matches_get_page(matches); ++ const size_t items_on_page __attribute__((unused)) = matches_get_count(matches); ++ ++ LOG_DBG( ++ "page-count: %zu, page-no: %zu, items-on-page: %zu, idx: %zu, max: %zu, " ++ "match-count: %zu", ++ matches->page_count, page_no, items_on_page, idx, ++ matches->max_matches_per_page, matches->match_count); ++ ++ if (idx >= items_on_page) ++ return false; ++ ++ idx += page_no * matches->max_matches_per_page; ++ ++ if (idx >= matches->match_count) ++ return false; ++ ++ matches->selected = idx; ++ return true; ++} ++ + bool + matches_selected_first(struct matches *matches) + { +diff --git a/match.h b/match.h +index 4100881..871635b 100644 +--- a/match.h ++++ b/match.h +@@ -53,6 +53,7 @@ size_t matches_get_total_count(const struct matches *matches); + size_t matches_get_match_index(const struct matches *matches); + + bool matches_selected_select(struct matches *matches, const char *string); ++bool matches_selected_select_idx(struct matches *matches, size_t idx); + + bool matches_selected_first(struct matches *matches); + bool matches_selected_last(struct matches *matches); +diff --git a/render.c b/render.c +index 403d7c9..3bc507c 100644 +--- a/render.c ++++ b/render.c +@@ -873,3 +873,22 @@ render_destroy(struct render *render) + fcft_destroy(render->font); + free(render); + } ++ ++int render_get_row_num(const struct render *render, int y) ++{ ++ const float scale = render->scale; ++ const int y_margin = render->y_margin; ++ const int inner_pad = render->inner_pad; ++ const int border_size = render->border_size; ++ const int row_height = render->row_height; ++ const int first_row = 1 * border_size + y_margin + row_height + inner_pad; ++ ++ y = floor(scale * y); ++ ++ if (y <= first_row) { ++ return -1; ++ } else { ++ y -= first_row; ++ return y / row_height; ++ } ++} +diff --git a/render.h b/render.h +index c097882..1f934f5 100644 +--- a/render.h ++++ b/render.h +@@ -30,3 +30,5 @@ void render_match_list( + const struct prompt *prompt, const struct matches *matches); + + int render_icon_size(const struct render *render); ++ ++int render_get_row_num(const struct render *render, int y); +diff --git a/wayland.c b/wayland.c +index 15f9e05..c2cf6a6 100644 +--- a/wayland.c ++++ b/wayland.c +@@ -1062,18 +1062,56 @@ static void + wl_pointer_motion(void *data, struct wl_pointer *wl_pointer, + uint32_t time, wl_fixed_t surface_x, wl_fixed_t surface_y) + { ++ struct seat *seat = data; ++ struct wayland *wayl = seat->wayl; ++ bool refresh = false; ++ ++ refresh = matches_selected_select_idx(wayl->matches, ++ render_get_row_num(wayl->render, wl_fixed_to_int(surface_y))); ++ ++ if (refresh) { ++ wayl_refresh(wayl); ++ } + } + + static void + wl_pointer_button(void *data, struct wl_pointer *wl_pointer, + uint32_t serial, uint32_t time, uint32_t button, uint32_t state) + { ++ struct seat *seat = data; ++ struct wayland *wayl = seat->wayl; ++ ++ // Button release ++ if (state == 0) { ++ // Left click ++ if (button == 272) { ++ execute_selected(seat, false, -1); ++ // Right click ++ } else if (button == 273) { ++ wayl->status = EXIT; ++ if (wayl->conf->dmenu.enabled) ++ wayl->exit_code = 2; ++ } ++ } + } + + static void + wl_pointer_axis(void *data, struct wl_pointer *wl_pointer, + uint32_t time, uint32_t axis, wl_fixed_t value) + { ++ struct seat *seat = data; ++ struct wayland *wayl = seat->wayl; ++ ++ bool refresh = false; ++ if (value < 0) { ++ refresh = matches_selected_prev_page(wayl->matches); ++ } else if (value > 0) { ++ refresh = matches_selected_next_page(wayl->matches); ++ } ++ ++ if (refresh) { ++ wayl_refresh(wayl); ++ } + } + + static void +-- +2.39.2 + + +From e023c4f6ceb8bd0fa9b5b1ed2b23af123c2811ed Mon Sep 17 00:00:00 2001 +From: alz +Date: Mon, 22 Jul 2024 01:07:56 -0400 +Subject: [PATCH 2/7] put the mouse stuff behind a config + +--- + config.c | 4 ++++ + config.h | 2 ++ + doc/fuzzel.1.scd | 4 ++++ + doc/fuzzel.ini.5.scd | 3 +++ + main.c | 10 ++++++++ + match.c | 4 ++++ + wayland.c | 54 +++++++++++++++++++++++++------------------- + 7 files changed, 58 insertions(+), 23 deletions(-) + +diff --git a/config.c b/config.c +index e236142..21aab3a 100644 +--- a/config.c ++++ b/config.c +@@ -778,6 +778,9 @@ parse_section_main(struct context *ctx) + else if (strcmp(key, "list-executables-in-path") == 0) + return value_to_bool(ctx, &conf->list_executables_in_path); + ++ else if (strcmp(key, "mouse-listener") == 0) ++ return value_to_bool(ctx, &conf->mouse_listener); ++ + else if (strcmp(key, "fields") == 0) { + _Static_assert(sizeof(conf->match_fields) == sizeof(int), + "enum is not 32-bit"); +@@ -1572,6 +1575,7 @@ config_load(struct config *conf, const char *conf_path, + .layer = ZWLR_LAYER_SHELL_V1_LAYER_TOP, + .exit_on_kb_focus_loss = true, + .list_executables_in_path = false, ++ .mouse_listener = false, + }; + + add_default_key_bindings(conf); +diff --git a/config.h b/config.h +index a52976c..99d3a52 100644 +--- a/config.h ++++ b/config.h +@@ -170,6 +170,8 @@ struct config { + bool exit_on_kb_focus_loss; + + bool list_executables_in_path; ++ ++ bool mouse_listener; + }; + + typedef tll(char *) config_override_t; +diff --git a/doc/fuzzel.1.scd b/doc/fuzzel.1.scd +index c46d9af..791a5e6 100644 +--- a/doc/fuzzel.1.scd ++++ b/doc/fuzzel.1.scd +@@ -302,6 +302,10 @@ or command line options: + *--log-no-syslog* + Disables syslog logging. Logging is only done on stderr. + ++*--mouse* ++ Allows choosing items with mouse left click, and cancelling fuzzel with ++ right click. ++ + *-v*,*--version* + Show the version number and quit + +diff --git a/doc/fuzzel.ini.5.scd b/doc/fuzzel.ini.5.scd +index e3dfc05..ee6a2c5 100644 +--- a/doc/fuzzel.ini.5.scd ++++ b/doc/fuzzel.ini.5.scd +@@ -411,6 +411,9 @@ done by setting _action=none_; e.g. *delete-line-forward=none*. + *last* + Select the last entry, on the last page. Default: _Control+End_. + ++*mouse-listener* ++ Allows selecting elements with the mouse ++ + *custom-1*, *custom-2*, ..., *custom-19* + Execute the currently selected entry, then exit with a non-zero + exit code. *custom-1* exits with exit code 10, *custom-2* with 11, +diff --git a/match.c b/match.c +index 7d5efaf..fe3903a 100644 +--- a/match.c ++++ b/match.c +@@ -362,6 +362,9 @@ matches_selected_select(struct matches *matches, const char *_string) + bool + matches_selected_select_idx(struct matches *matches, size_t idx) + { ++ if (idx < 0) ++ return false; ++ + const size_t page_no = matches_get_page(matches); + const size_t items_on_page __attribute__((unused)) = matches_get_count(matches); + +@@ -371,6 +374,7 @@ matches_selected_select_idx(struct matches *matches, size_t idx) + matches->page_count, page_no, items_on_page, idx, + matches->max_matches_per_page, matches->match_count); + ++ + if (idx >= items_on_page) + return false; + +diff --git a/wayland.c b/wayland.c +index c2cf6a6..8fff785 100644 +--- a/wayland.c ++++ b/wayland.c +@@ -1064,13 +1064,16 @@ wl_pointer_motion(void *data, struct wl_pointer *wl_pointer, + { + struct seat *seat = data; + struct wayland *wayl = seat->wayl; +- bool refresh = false; + +- refresh = matches_selected_select_idx(wayl->matches, +- render_get_row_num(wayl->render, wl_fixed_to_int(surface_y))); ++ if (wayl->conf->mouse_listener) { ++ bool refresh = false; + +- if (refresh) { +- wayl_refresh(wayl); ++ refresh = matches_selected_select_idx(wayl->matches, ++ render_get_row_num(wayl->render, wl_fixed_to_int(surface_y))); ++ ++ if (refresh) { ++ wayl_refresh(wayl); ++ } + } + } + +@@ -1081,16 +1084,18 @@ wl_pointer_button(void *data, struct wl_pointer *wl_pointer, + struct seat *seat = data; + struct wayland *wayl = seat->wayl; + +- // Button release +- if (state == 0) { +- // Left click +- if (button == 272) { +- execute_selected(seat, false, -1); +- // Right click +- } else if (button == 273) { +- wayl->status = EXIT; +- if (wayl->conf->dmenu.enabled) +- wayl->exit_code = 2; ++ if (wayl->conf->mouse_listener) { ++ // Button release ++ if (state == 0) { ++ // Left click ++ if (button == 0x110) { ++ execute_selected(seat, false, -1); ++ // Right click ++ } else if (button == 0x111) { ++ wayl->status = EXIT; ++ if (wayl->conf->dmenu.enabled) ++ wayl->exit_code = 2; ++ } + } + } + } +@@ -1102,15 +1107,18 @@ wl_pointer_axis(void *data, struct wl_pointer *wl_pointer, + struct seat *seat = data; + struct wayland *wayl = seat->wayl; + +- bool refresh = false; +- if (value < 0) { +- refresh = matches_selected_prev_page(wayl->matches); +- } else if (value > 0) { +- refresh = matches_selected_next_page(wayl->matches); +- } ++ if (wayl->conf->mouse_listener) { ++ bool refresh = false; + +- if (refresh) { +- wayl_refresh(wayl); ++ if (value < 0) { ++ refresh = matches_selected_prev_page(wayl->matches); ++ } else if (value > 0) { ++ refresh = matches_selected_next_page(wayl->matches); ++ } ++ ++ if (refresh) { ++ wayl_refresh(wayl); ++ } + } + } + +-- +2.39.2 + + +From 9e04a13fa2a6b442faaa1451700e04000f24734b Mon Sep 17 00:00:00 2001 +From: alz +Date: Mon, 22 Jul 2024 12:00:43 -0400 +Subject: [PATCH 3/7] Ignoring left clicks if they're in the prompt row + +--- + wayland.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/wayland.c b/wayland.c +index 8fff785..e7c0c2c 100644 +--- a/wayland.c ++++ b/wayland.c +@@ -1068,6 +1068,8 @@ wl_pointer_motion(void *data, struct wl_pointer *wl_pointer, + if (wayl->conf->mouse_listener) { + bool refresh = false; + ++ seat->pointer.y = wl_fixed_to_int(surface_y); ++ + refresh = matches_selected_select_idx(wayl->matches, + render_get_row_num(wayl->render, wl_fixed_to_int(surface_y))); + +@@ -1088,7 +1090,7 @@ wl_pointer_button(void *data, struct wl_pointer *wl_pointer, + // Button release + if (state == 0) { + // Left click +- if (button == 0x110) { ++ if (button == 0x110 && render_get_row_num(wayl->render, seat->pointer.y) >= 0) { + execute_selected(seat, false, -1); + // Right click + } else if (button == 0x111) { +-- +2.39.2 + + +From 607edc371b7ee48ec194ec2ce561d8e10d49923a Mon Sep 17 00:00:00 2001 +From: alz +Date: Mon, 22 Jul 2024 13:18:43 -0400 +Subject: [PATCH 4/7] Refactored so the data types are correct + +--- + match.c | 36 ++++++++++++------------------------ + render.c | 14 +++++++++----- + render.h | 2 +- + wayland.c | 28 +++++++++++++++++----------- + 4 files changed, 39 insertions(+), 41 deletions(-) + +diff --git a/match.c b/match.c +index fe3903a..a16f903 100644 +--- a/match.c ++++ b/match.c +@@ -278,8 +278,8 @@ matches_get_page(const struct matches *matches) + : matches->selected; + } + +-const struct match * +-matches_get(const struct matches *matches, size_t idx) ++size_t ++match_get_idx(const struct matches *matches, size_t idx) + { + const size_t page_no = matches_get_page(matches); + const size_t items_on_page __attribute__((unused)) = matches_get_count(matches); +@@ -290,11 +290,17 @@ matches_get(const struct matches *matches, size_t idx) + matches->page_count, page_no, items_on_page, idx, + matches->max_matches_per_page, matches->match_count); + +- assert(idx < items_on_page); ++ assert(idx >= 0 && idx < items_on_page); + idx += page_no * matches->max_matches_per_page; + + assert(idx < matches->match_count); +- return &matches->matches[idx]; ++ return idx; ++} ++ ++const struct match * ++matches_get(const struct matches *matches, size_t idx) ++{ ++ return &matches->matches[match_get_idx(matches, idx)]; + } + + const struct match * +@@ -362,28 +368,10 @@ matches_selected_select(struct matches *matches, const char *_string) + bool + matches_selected_select_idx(struct matches *matches, size_t idx) + { +- if (idx < 0) ++ if (idx == -1) + return false; + +- const size_t page_no = matches_get_page(matches); +- const size_t items_on_page __attribute__((unused)) = matches_get_count(matches); +- +- LOG_DBG( +- "page-count: %zu, page-no: %zu, items-on-page: %zu, idx: %zu, max: %zu, " +- "match-count: %zu", +- matches->page_count, page_no, items_on_page, idx, +- matches->max_matches_per_page, matches->match_count); +- +- +- if (idx >= items_on_page) +- return false; +- +- idx += page_no * matches->max_matches_per_page; +- +- if (idx >= matches->match_count) +- return false; +- +- matches->selected = idx; ++ matches->selected = match_get_idx(matches, idx); + return true; + } + +diff --git a/render.c b/render.c +index 3bc507c..1dcefc9 100644 +--- a/render.c ++++ b/render.c +@@ -874,7 +874,8 @@ render_destroy(struct render *render) + free(render); + } + +-int render_get_row_num(const struct render *render, int y) ++size_t ++render_get_row_num(const struct render *render, int y, size_t match_count) + { + const float scale = render->scale; + const int y_margin = render->y_margin; +@@ -882,13 +883,16 @@ int render_get_row_num(const struct render *render, int y) + const int border_size = render->border_size; + const int row_height = render->row_height; + const int first_row = 1 * border_size + y_margin + row_height + inner_pad; ++ const int last_row = first_row + match_count*row_height; + + y = floor(scale * y); + +- if (y <= first_row) { +- return -1; +- } else { ++ size_t row = -1; ++ ++ if (y >= first_row && y < last_row) { + y -= first_row; +- return y / row_height; ++ row = y / row_height; + } ++ ++ return row; + } +diff --git a/render.h b/render.h +index 1f934f5..c257004 100644 +--- a/render.h ++++ b/render.h +@@ -31,4 +31,4 @@ void render_match_list( + + int render_icon_size(const struct render *render); + +-int render_get_row_num(const struct render *render, int y); ++size_t render_get_row_num(const struct render *render, int y, size_t match_count); +diff --git a/wayland.c b/wayland.c +index e7c0c2c..56ff829 100644 +--- a/wayland.c ++++ b/wayland.c +@@ -1058,6 +1058,19 @@ wl_pointer_leave(void *data, struct wl_pointer *wl_pointer, + seat->pointer.serial = serial; + } + ++static void ++select_hovered_match(struct wayland *wayl, int y) ++{ ++ bool refresh = false; ++ ++ refresh = matches_selected_select_idx(wayl->matches, ++ render_get_row_num(wayl->render, y, matches_get_count(wayl->matches))); ++ ++ if (refresh) { ++ wayl_refresh(wayl); ++ } ++} ++ + static void + wl_pointer_motion(void *data, struct wl_pointer *wl_pointer, + uint32_t time, wl_fixed_t surface_x, wl_fixed_t surface_y) +@@ -1066,16 +1079,8 @@ wl_pointer_motion(void *data, struct wl_pointer *wl_pointer, + struct wayland *wayl = seat->wayl; + + if (wayl->conf->mouse_listener) { +- bool refresh = false; +- + seat->pointer.y = wl_fixed_to_int(surface_y); +- +- refresh = matches_selected_select_idx(wayl->matches, +- render_get_row_num(wayl->render, wl_fixed_to_int(surface_y))); +- +- if (refresh) { +- wayl_refresh(wayl); +- } ++ select_hovered_match(wayl, seat->pointer.y); + } + } + +@@ -1090,7 +1095,8 @@ wl_pointer_button(void *data, struct wl_pointer *wl_pointer, + // Button release + if (state == 0) { + // Left click +- if (button == 0x110 && render_get_row_num(wayl->render, seat->pointer.y) >= 0) { ++ if (button == 0x110 && ++ render_get_row_num(wayl->render, seat->pointer.y, matches_get_count(wayl->matches)) != -1) { + execute_selected(seat, false, -1); + // Right click + } else if (button == 0x111) { +@@ -1119,7 +1125,7 @@ wl_pointer_axis(void *data, struct wl_pointer *wl_pointer, + } + + if (refresh) { +- wayl_refresh(wayl); ++ select_hovered_match(wayl, seat->pointer.y); + } + } + } +-- +2.39.2 + + +From f4d4918ebd6b996deff617c2750000904d1f2d29 Mon Sep 17 00:00:00 2001 +From: alz +Date: Mon, 22 Jul 2024 13:37:03 -0400 +Subject: [PATCH 5/7] made the hovered row index an attribute of the seat + pointer + +--- + wayland.c | 20 +++++++++++--------- + 1 file changed, 11 insertions(+), 9 deletions(-) + +diff --git a/wayland.c b/wayland.c +index 56ff829..ab88598 100644 +--- a/wayland.c ++++ b/wayland.c +@@ -148,6 +148,8 @@ struct seat { + struct wl_cursor_theme *theme; + struct wl_cursor *cursor; + float scale; ++ ++ size_t hovered_row_idx; + } pointer; + }; + +@@ -1059,12 +1061,10 @@ wl_pointer_leave(void *data, struct wl_pointer *wl_pointer, + } + + static void +-select_hovered_match(struct wayland *wayl, int y) ++select_hovered_match(struct wayland *wayl, size_t idx) + { + bool refresh = false; +- +- refresh = matches_selected_select_idx(wayl->matches, +- render_get_row_num(wayl->render, y, matches_get_count(wayl->matches))); ++ refresh = matches_selected_select_idx(wayl->matches,idx); + + if (refresh) { + wayl_refresh(wayl); +@@ -1079,8 +1079,11 @@ wl_pointer_motion(void *data, struct wl_pointer *wl_pointer, + struct wayland *wayl = seat->wayl; + + if (wayl->conf->mouse_listener) { +- seat->pointer.y = wl_fixed_to_int(surface_y); +- select_hovered_match(wayl, seat->pointer.y); ++ seat->pointer.hovered_row_idx = ++ render_get_row_num(wayl->render, ++ wl_fixed_to_int(surface_y), ++ matches_get_count(wayl->matches)); ++ select_hovered_match(wayl, seat->pointer.hovered_row_idx); + } + } + +@@ -1095,8 +1098,7 @@ wl_pointer_button(void *data, struct wl_pointer *wl_pointer, + // Button release + if (state == 0) { + // Left click +- if (button == 0x110 && +- render_get_row_num(wayl->render, seat->pointer.y, matches_get_count(wayl->matches)) != -1) { ++ if (button == 0x110 && seat->pointer.hovered_row_idx != -1) { + execute_selected(seat, false, -1); + // Right click + } else if (button == 0x111) { +@@ -1125,7 +1127,7 @@ wl_pointer_axis(void *data, struct wl_pointer *wl_pointer, + } + + if (refresh) { +- select_hovered_match(wayl, seat->pointer.y); ++ select_hovered_match(wayl, seat->pointer.hovered_row_idx); + } + } + } +-- +2.39.2 + + +From ef4b0160b3c6e04da7b4bf6a0e6b7d0ac06b54ef Mon Sep 17 00:00:00 2001 +From: alz +Date: Tue, 23 Jul 2024 16:35:44 -0400 +Subject: [PATCH 6/7] Refreshing display less often + +--- + render.c | 2 +- + wayland.c | 7 +++++-- + 2 files changed, 6 insertions(+), 3 deletions(-) + +diff --git a/render.c b/render.c +index 1dcefc9..505f570 100644 +--- a/render.c ++++ b/render.c +@@ -839,7 +839,7 @@ render_set_font(struct render *render, struct fcft_font *font, + border_size; + + LOG_DBG("x-margin: %d, y-margin: %d, border: %d, row-height: %d, " +- "icon-height: %d, height: %d, width: %d, scale: %d", ++ "icon-height: %d, height: %d, width: %d, scale: %f", + x_margin, y_margin, border_size, row_height, icon_height, + height, width, scale); + +diff --git a/wayland.c b/wayland.c +index ab88598..19e902a 100644 +--- a/wayland.c ++++ b/wayland.c +@@ -1079,11 +1079,14 @@ wl_pointer_motion(void *data, struct wl_pointer *wl_pointer, + struct wayland *wayl = seat->wayl; + + if (wayl->conf->mouse_listener) { +- seat->pointer.hovered_row_idx = ++ size_t hovered_row = + render_get_row_num(wayl->render, + wl_fixed_to_int(surface_y), + matches_get_count(wayl->matches)); +- select_hovered_match(wayl, seat->pointer.hovered_row_idx); ++ if (hovered_row != seat->pointer.hovered_row_idx) { ++ seat->pointer.hovered_row_idx = hovered_row; ++ select_hovered_match(wayl, seat->pointer.hovered_row_idx); ++ } + } + } + +-- +2.39.2 + + +From 761aabf6b7fc55203e23be76a044bbea3e8d99be Mon Sep 17 00:00:00 2001 +From: alz +Date: Mon, 29 Jul 2024 13:01:12 -0400 +Subject: [PATCH 7/7] Removed config, refactored hovered row selection + +--- + config.c | 4 --- + config.h | 2 -- + doc/fuzzel.1.scd | 4 --- + doc/fuzzel.ini.5.scd | 3 -- + main.c | 10 ------ + match.c | 12 +++---- + match.h | 6 ++-- + render.c | 9 ++--- + render.h | 4 ++- + wayland.c | 78 +++++++++++++++++++++----------------------- + 10 files changed, 54 insertions(+), 78 deletions(-) + +diff --git a/config.c b/config.c +index 21aab3a..e236142 100644 +--- a/config.c ++++ b/config.c +@@ -778,9 +778,6 @@ parse_section_main(struct context *ctx) + else if (strcmp(key, "list-executables-in-path") == 0) + return value_to_bool(ctx, &conf->list_executables_in_path); + +- else if (strcmp(key, "mouse-listener") == 0) +- return value_to_bool(ctx, &conf->mouse_listener); +- + else if (strcmp(key, "fields") == 0) { + _Static_assert(sizeof(conf->match_fields) == sizeof(int), + "enum is not 32-bit"); +@@ -1575,7 +1572,6 @@ config_load(struct config *conf, const char *conf_path, + .layer = ZWLR_LAYER_SHELL_V1_LAYER_TOP, + .exit_on_kb_focus_loss = true, + .list_executables_in_path = false, +- .mouse_listener = false, + }; + + add_default_key_bindings(conf); +diff --git a/config.h b/config.h +index 99d3a52..a52976c 100644 +--- a/config.h ++++ b/config.h +@@ -170,8 +170,6 @@ struct config { + bool exit_on_kb_focus_loss; + + bool list_executables_in_path; +- +- bool mouse_listener; + }; + + typedef tll(char *) config_override_t; +diff --git a/doc/fuzzel.1.scd b/doc/fuzzel.1.scd +index 791a5e6..c46d9af 100644 +--- a/doc/fuzzel.1.scd ++++ b/doc/fuzzel.1.scd +@@ -302,10 +302,6 @@ or command line options: + *--log-no-syslog* + Disables syslog logging. Logging is only done on stderr. + +-*--mouse* +- Allows choosing items with mouse left click, and cancelling fuzzel with +- right click. +- + *-v*,*--version* + Show the version number and quit + +diff --git a/doc/fuzzel.ini.5.scd b/doc/fuzzel.ini.5.scd +index ee6a2c5..e3dfc05 100644 +--- a/doc/fuzzel.ini.5.scd ++++ b/doc/fuzzel.ini.5.scd +@@ -411,9 +411,6 @@ done by setting _action=none_; e.g. *delete-line-forward=none*. + *last* + Select the last entry, on the last page. Default: _Control+End_. + +-*mouse-listener* +- Allows selecting elements with the mouse +- + *custom-1*, *custom-2*, ..., *custom-19* + Execute the currently selected entry, then exit with a non-zero + exit code. *custom-1* exits with exit code 10, *custom-2* with 11, +diff --git a/match.c b/match.c +index a16f903..48c6e4f 100644 +--- a/match.c ++++ b/match.c +@@ -290,7 +290,7 @@ match_get_idx(const struct matches *matches, size_t idx) + matches->page_count, page_no, items_on_page, idx, + matches->max_matches_per_page, matches->match_count); + +- assert(idx >= 0 && idx < items_on_page); ++ assert(idx < items_on_page); + idx += page_no * matches->max_matches_per_page; + + assert(idx < matches->match_count); +@@ -366,7 +366,7 @@ matches_selected_select(struct matches *matches, const char *_string) + } + + bool +-matches_selected_select_idx(struct matches *matches, size_t idx) ++matches_idx_select(struct matches *matches, size_t idx) + { + if (idx == -1) + return false; +@@ -427,14 +427,14 @@ matches_selected_next(struct matches *matches, bool wrap) + } + + bool +-matches_selected_prev_page(struct matches *matches) ++matches_selected_prev_page(struct matches *matches, bool scrolling) + { + const size_t page_no = matches_get_page(matches); + if (page_no > 0) { + assert(matches->selected >= matches->max_matches_per_page); + matches->selected -= matches->max_matches_per_page; + return true; +- } else if (matches->selected > 0) { ++ } else if (!scrolling && matches->selected > 0) { + matches->selected = 0; + return true; + } +@@ -443,7 +443,7 @@ matches_selected_prev_page(struct matches *matches) + } + + bool +-matches_selected_next_page(struct matches *matches) ++matches_selected_next_page(struct matches *matches, bool scrolling) + { + const size_t page_no = matches_get_page(matches); + if (page_no + 1 < matches->page_count) { +@@ -451,7 +451,7 @@ matches_selected_next_page(struct matches *matches) + matches->selected + matches->max_matches_per_page, + matches->match_count - 1); + return true; +- } else if (matches->selected < matches->match_count - 1) { ++ } else if (!scrolling && matches->selected < matches->match_count - 1) { + matches->selected = matches->match_count - 1; + return true; + } +diff --git a/match.h b/match.h +index 871635b..35c5d5e 100644 +--- a/match.h ++++ b/match.h +@@ -53,7 +53,7 @@ size_t matches_get_total_count(const struct matches *matches); + size_t matches_get_match_index(const struct matches *matches); + + bool matches_selected_select(struct matches *matches, const char *string); +-bool matches_selected_select_idx(struct matches *matches, size_t idx); ++bool matches_idx_select(struct matches *matches, size_t idx); + + bool matches_selected_first(struct matches *matches); + bool matches_selected_last(struct matches *matches); +@@ -61,5 +61,5 @@ bool matches_selected_last(struct matches *matches); + bool matches_selected_prev(struct matches *matches, bool wrap); + bool matches_selected_next(struct matches *matches, bool wrap); + +-bool matches_selected_prev_page(struct matches *matches); +-bool matches_selected_next_page(struct matches *matches); ++bool matches_selected_prev_page(struct matches *matches, bool scrolling); ++bool matches_selected_next_page(struct matches *matches, bool scrolling); +diff --git a/render.c b/render.c +index 505f570..ef9aaad 100644 +--- a/render.c ++++ b/render.c +@@ -875,7 +875,8 @@ render_destroy(struct render *render) + } + + size_t +-render_get_row_num(const struct render *render, int y, size_t match_count) ++render_get_row_num(const struct render *render, int y, ++ const struct matches *matches) + { + const float scale = render->scale; + const int y_margin = render->y_margin; +@@ -883,15 +884,15 @@ render_get_row_num(const struct render *render, int y, size_t match_count) + const int border_size = render->border_size; + const int row_height = render->row_height; + const int first_row = 1 * border_size + y_margin + row_height + inner_pad; +- const int last_row = first_row + match_count*row_height; ++ const size_t match_count = matches_get_count(matches); ++ const size_t last_row = first_row + match_count*row_height; + + y = floor(scale * y); + + size_t row = -1; + + if (y >= first_row && y < last_row) { +- y -= first_row; +- row = y / row_height; ++ row = (y - first_row) / row_height; + } + + return row; +diff --git a/render.h b/render.h +index c257004..16887f3 100644 +--- a/render.h ++++ b/render.h +@@ -31,4 +31,6 @@ void render_match_list( + + int render_icon_size(const struct render *render); + +-size_t render_get_row_num(const struct render *render, int y, size_t match_count); ++size_t render_get_row_num( ++ const struct render *render, int y, ++ const struct matches *matches); +diff --git a/wayland.c b/wayland.c +index 19e902a..541496d 100644 +--- a/wayland.c ++++ b/wayland.c +@@ -16,6 +16,7 @@ + #include + #include + ++#include + #include + #include + #include +@@ -142,14 +143,13 @@ struct seat { + + int x; + int y; ++ size_t hovered_row_idx; + + struct wl_surface *surface; + struct wp_viewport *viewport; + struct wl_cursor_theme *theme; + struct wl_cursor *cursor; + float scale; +- +- size_t hovered_row_idx; + } pointer; + }; + +@@ -706,7 +706,7 @@ execute_binding(struct seat *seat, const struct key_binding *binding, bool *refr + return true; + + case BIND_ACTION_MATCHES_PREV_PAGE: +- *refresh = matches_selected_prev_page(wayl->matches); ++ *refresh = matches_selected_prev_page(wayl->matches, false); + return true; + + case BIND_ACTION_MATCHES_NEXT: +@@ -718,7 +718,7 @@ execute_binding(struct seat *seat, const struct key_binding *binding, bool *refr + return true; + + case BIND_ACTION_MATCHES_NEXT_PAGE: +- *refresh = matches_selected_next_page(wayl->matches); ++ *refresh = matches_selected_next_page(wayl->matches, false); + return true; + + case BIND_ACTION_MATCHES_FIRST: +@@ -1061,12 +1061,22 @@ wl_pointer_leave(void *data, struct wl_pointer *wl_pointer, + } + + static void +-select_hovered_match(struct wayland *wayl, size_t idx) ++select_hovered_match(struct seat *seat, bool refresh_always) + { ++ struct wayland *wayl = seat->wayl; + bool refresh = false; +- refresh = matches_selected_select_idx(wayl->matches,idx); + +- if (refresh) { ++ size_t hovered_row = ++ render_get_row_num(wayl->render, ++ seat->pointer.y, ++ wayl->matches); ++ ++ if (hovered_row != seat->pointer.hovered_row_idx) { ++ seat->pointer.hovered_row_idx = hovered_row; ++ refresh = matches_idx_select(wayl->matches,hovered_row); ++ } ++ ++ if (refresh_always || refresh) { + wayl_refresh(wayl); + } + } +@@ -1076,18 +1086,11 @@ wl_pointer_motion(void *data, struct wl_pointer *wl_pointer, + uint32_t time, wl_fixed_t surface_x, wl_fixed_t surface_y) + { + struct seat *seat = data; +- struct wayland *wayl = seat->wayl; + +- if (wayl->conf->mouse_listener) { +- size_t hovered_row = +- render_get_row_num(wayl->render, +- wl_fixed_to_int(surface_y), +- matches_get_count(wayl->matches)); +- if (hovered_row != seat->pointer.hovered_row_idx) { +- seat->pointer.hovered_row_idx = hovered_row; +- select_hovered_match(wayl, seat->pointer.hovered_row_idx); +- } +- } ++ seat->pointer.x = wl_fixed_to_int(surface_x); ++ seat->pointer.y = wl_fixed_to_int(surface_y); ++ ++ select_hovered_match(seat, false); + } + + static void +@@ -1097,18 +1100,14 @@ wl_pointer_button(void *data, struct wl_pointer *wl_pointer, + struct seat *seat = data; + struct wayland *wayl = seat->wayl; + +- if (wayl->conf->mouse_listener) { +- // Button release +- if (state == 0) { +- // Left click +- if (button == 0x110 && seat->pointer.hovered_row_idx != -1) { +- execute_selected(seat, false, -1); +- // Right click +- } else if (button == 0x111) { +- wayl->status = EXIT; +- if (wayl->conf->dmenu.enabled) +- wayl->exit_code = 2; +- } ++ if (state == WL_POINTER_BUTTON_STATE_RELEASED) { ++ if (button == BTN_LEFT && seat->pointer.hovered_row_idx != -1) { ++ execute_selected(seat, false, -1); ++ } else if (button == BTN_RIGHT) { ++ // Same as pressing ESC ++ wayl->status = EXIT; ++ if (wayl->conf->dmenu.enabled) ++ wayl->exit_code = 2; + } + } + } +@@ -1119,19 +1118,16 @@ wl_pointer_axis(void *data, struct wl_pointer *wl_pointer, + { + struct seat *seat = data; + struct wayland *wayl = seat->wayl; ++ bool refresh = false; + +- if (wayl->conf->mouse_listener) { +- bool refresh = false; ++ if (value < 0) { ++ refresh = matches_selected_prev_page(wayl->matches, true); ++ } else if (value > 0) { ++ refresh = matches_selected_next_page(wayl->matches, true); ++ } + +- if (value < 0) { +- refresh = matches_selected_prev_page(wayl->matches); +- } else if (value > 0) { +- refresh = matches_selected_next_page(wayl->matches); +- } +- +- if (refresh) { +- select_hovered_match(wayl, seat->pointer.hovered_row_idx); +- } ++ if (refresh) { ++ select_hovered_match(seat, true); + } + } + +-- +2.39.2 diff --git a/user/wm/hyprland/patches/waybarbatupdate.patch b/user/wm/hyprland/patches/waybarbatupdate.patch new file mode 100644 index 0000000..364c92e --- /dev/null +++ b/user/wm/hyprland/patches/waybarbatupdate.patch @@ -0,0 +1,192 @@ +From f4608b3e312448b37a8f9d6351154026e67c680a Mon Sep 17 00:00:00 2001 +From: schmop +Date: Thu, 25 Jul 2024 01:40:49 +0200 +Subject: [PATCH] Fix battery status changes not being detected + +Historically we listened to /sys/class/poewr_supply inotify events, +which does not seem to work anymore. +We switched now to udev netlink kernel events. +--- + include/modules/battery.hpp | 8 +++++-- + include/util/udev_deleter.hpp | 21 ++++++++++++++++++ + src/modules/battery.cpp | 40 +++++++++++++++++++--------------- + src/util/backlight_backend.cpp | 17 +-------------- + 4 files changed, 51 insertions(+), 35 deletions(-) + create mode 100644 include/util/udev_deleter.hpp + +diff --git a/include/modules/battery.hpp b/include/modules/battery.hpp +index 8e1a2ad2b..fc403be05 100644 +--- a/include/modules/battery.hpp ++++ b/include/modules/battery.hpp +@@ -5,8 +5,11 @@ + #include + #if defined(__linux__) + #include ++#include "util/udev_deleter.hpp" + #endif + ++#include ++ + #include + #include + #include +@@ -36,11 +39,12 @@ class Battery : public ALabel { + const std::string formatTimeRemaining(float hoursRemaining); + void setBarClass(std::string&); + +- int global_watch; + std::map batteries_; ++ std::unique_ptr udev_; ++ std::array poll_fds_; ++ std::unique_ptr mon_; + fs::path adapter_; + int battery_watch_fd_; +- int global_watch_fd_; + std::mutex battery_list_mutex_; + std::string old_status_; + bool warnFirstTime_{true}; +diff --git a/include/util/udev_deleter.hpp b/include/util/udev_deleter.hpp +new file mode 100644 +index 000000000..b2f1e538b +--- /dev/null ++++ b/include/util/udev_deleter.hpp +@@ -0,0 +1,21 @@ ++#pragma once ++ ++#include ++ ++namespace waybar::util { ++struct UdevDeleter { ++ void operator()(udev *ptr) const { udev_unref(ptr); } ++}; ++ ++struct UdevDeviceDeleter { ++ void operator()(udev_device *ptr) const { udev_device_unref(ptr); } ++}; ++ ++struct UdevEnumerateDeleter { ++ void operator()(udev_enumerate *ptr) const { udev_enumerate_unref(ptr); } ++}; ++ ++struct UdevMonitorDeleter { ++ void operator()(udev_monitor *ptr) const { udev_monitor_unref(ptr); } ++}; ++} // namespace waybar::util +\ No newline at end of file +diff --git a/src/modules/battery.cpp b/src/modules/battery.cpp +index d87cc6129..bad72e6b0 100644 +--- a/src/modules/battery.cpp ++++ b/src/modules/battery.cpp +@@ -5,6 +5,9 @@ + #include + #endif + #include ++#include ++#include ++#include + + #include + waybar::modules::Battery::Battery(const std::string& id, const Bar& bar, const Json::Value& config) +@@ -14,17 +17,18 @@ waybar::modules::Battery::Battery(const std::string& id, const Bar& bar, const J + if (battery_watch_fd_ == -1) { + throw std::runtime_error("Unable to listen batteries."); + } +- +- global_watch_fd_ = inotify_init1(IN_CLOEXEC); +- if (global_watch_fd_ == -1) { +- throw std::runtime_error("Unable to listen batteries."); ++ udev_ = std::unique_ptr(udev_new()); ++ if (udev_ == nullptr) { ++ throw std::runtime_error("udev_new failed"); + } +- +- // Watch the directory for any added or removed batteries +- global_watch = inotify_add_watch(global_watch_fd_, data_dir_.c_str(), IN_CREATE | IN_DELETE); +- if (global_watch < 0) { +- throw std::runtime_error("Could not watch for battery plug/unplug"); ++ mon_ = std::unique_ptr(udev_monitor_new_from_netlink(udev_.get(), "kernel")); ++ if (mon_ == nullptr) { ++ throw std::runtime_error("udev monitor new failed"); + } ++ if (udev_monitor_filter_add_match_subsystem_devtype(mon_.get(), "power_supply", nullptr) < 0) { ++ throw std::runtime_error("udev failed to add monitor filter"); ++ } ++ udev_monitor_enable_receiving(mon_.get()); + #endif + worker(); + } +@@ -33,11 +37,6 @@ waybar::modules::Battery::~Battery() { + #if defined(__linux__) + std::lock_guard guard(battery_list_mutex_); + +- if (global_watch >= 0) { +- inotify_rm_watch(global_watch_fd_, global_watch); +- } +- close(global_watch_fd_); +- + for (auto it = batteries_.cbegin(), next_it = it; it != batteries_.cend(); it = next_it) { + ++next_it; + auto watch_id = (*it).second; +@@ -74,12 +73,18 @@ void waybar::modules::Battery::worker() { + dp.emit(); + }; + thread_battery_update_ = [this] { +- struct inotify_event event = {0}; +- int nbytes = read(global_watch_fd_, &event, sizeof(event)); +- if (nbytes != sizeof(event) || event.mask & IN_IGNORED) { ++ poll_fds_[0].revents = 0; ++ poll_fds_[0].events = POLLIN; ++ poll_fds_[0].fd = udev_monitor_get_fd(mon_.get()); ++ int ret = poll(poll_fds_.data(), poll_fds_.size(), -1); ++ if (ret < 0) { + thread_.stop(); + return; + } ++ if ((poll_fds_[0].revents & POLLIN) != 0) { ++ signalfd_siginfo signal_info; ++ read(poll_fds_[0].fd, &signal_info, sizeof(signal_info)); ++ } + refreshBatteries(); + dp.emit(); + }; +@@ -668,6 +673,7 @@ auto waybar::modules::Battery::update() -> void { + status = getAdapterStatus(capacity); + } + auto status_pretty = status; ++ puts(status.c_str()); + // Transform to lowercase and replace space with dash + std::transform(status.begin(), status.end(), status.begin(), + [](char ch) { return ch == ' ' ? '-' : std::tolower(ch); }); +diff --git a/src/util/backlight_backend.cpp b/src/util/backlight_backend.cpp +index bb102cd93..df6afd564 100644 +--- a/src/util/backlight_backend.cpp ++++ b/src/util/backlight_backend.cpp +@@ -1,4 +1,5 @@ + #include "util/backlight_backend.hpp" ++#include "util/udev_deleter.hpp" + + #include + #include +@@ -29,22 +30,6 @@ class FileDescriptor { + int fd_; + }; + +-struct UdevDeleter { +- void operator()(udev *ptr) { udev_unref(ptr); } +-}; +- +-struct UdevDeviceDeleter { +- void operator()(udev_device *ptr) { udev_device_unref(ptr); } +-}; +- +-struct UdevEnumerateDeleter { +- void operator()(udev_enumerate *ptr) { udev_enumerate_unref(ptr); } +-}; +- +-struct UdevMonitorDeleter { +- void operator()(udev_monitor *ptr) { udev_monitor_unref(ptr); } +-}; +- + void check_eq(int rc, int expected, const char *message = "eq, rc was: ") { + if (rc != expected) { + throw std::runtime_error(fmt::format(fmt::runtime(message), rc)); diff --git a/user/wm/hyprland/patches/waybarpaupdate.patch b/user/wm/hyprland/patches/waybarpaupdate.patch new file mode 100644 index 0000000..f1c22cd --- /dev/null +++ b/user/wm/hyprland/patches/waybarpaupdate.patch @@ -0,0 +1,71 @@ +diff --git a/include/util/audio_backend.hpp b/include/util/audio_backend.hpp +index 2f53103e5..3737ae264 100644 +--- a/include/util/audio_backend.hpp ++++ b/include/util/audio_backend.hpp +@@ -38,6 +38,8 @@ class AudioBackend { + std::string desc_; + std::string monitor_; + std::string current_sink_name_; ++ std::string default_sink_name; ++ bool default_sink_running_; + bool current_sink_running_; + // SOURCE + uint32_t source_idx_{0}; +diff --git a/src/util/audio_backend.cpp b/src/util/audio_backend.cpp +index 3d90b6d5a..73aac148b 100644 +--- a/src/util/audio_backend.cpp ++++ b/src/util/audio_backend.cpp +@@ -1,9 +1,12 @@ + #include "util/audio_backend.hpp" + + #include ++#include + #include ++#include + #include + #include ++#include + + #include + #include +@@ -139,6 +142,10 @@ void AudioBackend::sinkInfoCb(pa_context * /*context*/, const pa_sink_info *i, i + void *data) { + if (i == nullptr) return; + ++ auto running = i->state == PA_SINK_RUNNING; ++ auto idle = i->state == PA_SINK_IDLE; ++ spdlog::trace("Sink name {} Running:[{}] Idle:[{}]", i->name, running, idle); ++ + auto *backend = static_cast(data); + + if (!backend->ignored_sinks_.empty()) { +@@ -155,11 +162,19 @@ void AudioBackend::sinkInfoCb(pa_context * /*context*/, const pa_sink_info *i, i + } + } + ++ backend->default_sink_running_ = backend->default_sink_name == i->name && ++ (i->state == PA_SINK_RUNNING || i->state == PA_SINK_IDLE); ++ ++ if (i->name != backend->default_sink_name && !backend->default_sink_running_) { ++ return; ++ } ++ + if (backend->current_sink_name_ == i->name) { +- backend->current_sink_running_ = i->state == PA_SINK_RUNNING; ++ backend->current_sink_running_ = (i->state == PA_SINK_RUNNING || i->state == PA_SINK_IDLE); + } + +- if (!backend->current_sink_running_ && i->state == PA_SINK_RUNNING) { ++ if (!backend->current_sink_running_ && ++ (i->state == PA_SINK_RUNNING || i->state == PA_SINK_IDLE)) { + backend->current_sink_name_ = i->name; + backend->current_sink_running_ = true; + } +@@ -207,5 +222,6 @@ void AudioBackend::sourceInfoCb(pa_context * /*context*/, const pa_source_info * + void AudioBackend::serverInfoCb(pa_context *context, const pa_server_info *i, void *data) { + auto *backend = static_cast(data); + backend->current_sink_name_ = i->default_sink_name; ++ backend->default_sink_name = i->default_sink_name; + backend->default_source_name_ = i->default_source_name; + + pa_context_get_sink_info_list(context, sinkInfoCb, data);