diff --git a/fuzzel-opening-animation/0001-fuzzel-animation.patch b/fuzzel-opening-animation/0001-fuzzel-animation.patch new file mode 100644 index 0000000..94243dc --- /dev/null +++ b/fuzzel-opening-animation/0001-fuzzel-animation.patch @@ -0,0 +1,220 @@ +From 669b92aa69ee4e102e84555b30cb4b589dbcf2da Mon Sep 17 00:00:00 2001 +From: jrosh +Date: Sun, 10 Aug 2025 14:32:31 +0200 +Subject: [PATCH] expand animation + +--- + main.c | 18 ++++++++++-- + render.c | 89 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-- + render.h | 3 ++ + 3 files changed, 105 insertions(+), 5 deletions(-) + +diff --git a/main.c b/main.c +index 4562bda..738aa0e 100644 +--- a/main.c ++++ b/main.c +@@ -673,6 +673,7 @@ process_event(struct context *ctx, enum event_type event) + wayl_resized(wayl); + } + ++ render_start_expand_animation(ctx->render); + wayl_ready_to_display(wayl); + } + +@@ -714,6 +715,7 @@ process_event(struct context *ctx, enum event_type event) + (!(conf->dmenu.enabled && conf->minimal_lines) || + apps->count >= conf->lines)) + { ++ render_start_expand_animation(ctx->render); + wayl_ready_to_display(wayl); + } + break; +@@ -2218,6 +2220,7 @@ main(int argc, char *const *argv) + if (!conf.dmenu.exit_immediately_if_empty && + !(conf.dmenu.enabled && conf.minimal_lines)) + { ++ render_start_expand_animation(ctx.render); + wayl_ready_to_display(wayl); + } + +@@ -2225,8 +2228,19 @@ main(int argc, char *const *argv) + + while (true) { + wayl_flush(wayl); +- if (!fdm_poll(fdm)) +- break; ++ ++ if (render_animation_active(ctx.render)) { ++ wayl_refresh(wayl); ++ // Force immediate poll return to keep animation smooth ++ // struct timespec timeout = {0, 16666666}; // 16ms for ~60fps ++ struct timespec timeout = {0, 6944444}; // 6.944ms for 144fps ++ nanosleep(&timeout, NULL); ++ if (!fdm_poll(fdm)) ++ break; ++ } else { ++ if (!fdm_poll(fdm)) ++ break; ++ } + } + + if (wayl_update_cache(wayl)) +diff --git a/render.c b/render.c +index 2d5645f..67439e3 100644 +--- a/render.c ++++ b/render.c +@@ -51,6 +51,12 @@ struct thread_context { + int my_id; + }; + ++struct animation_state { ++ bool active; ++ uint64_t start_time; ++ uint64_t duration; ++}; ++ + struct render { + const struct config *conf; + struct fcft_font *font; +@@ -60,7 +66,8 @@ struct render { + /* Cached fcft text runs */ + struct fcft_text_run *prompt_text_run; + struct fcft_text_run *placeholder_text_run; +- ++ struct animation_state animation; ++ + /* Cached selection corners */ + pixman_image_t *selection_corners; + +@@ -256,6 +263,44 @@ render_rounded_rectangle(pixman_image_t* dest, pixman_color_t* background, + } + } + ++void ++render_start_expand_animation(struct render *render) ++{ ++ struct timespec now; ++ clock_gettime(CLOCK_MONOTONIC, &now); ++ render->animation.start_time = now.tv_sec * 1000000000 + now.tv_nsec; ++ render->animation.active = true; ++} ++ ++static float ++get_animation_progress(struct render *render) ++{ ++ if (!render->animation.active) ++ return 1.0f; ++ ++ struct timespec now; ++ clock_gettime(CLOCK_MONOTONIC, &now); ++ uint64_t current_time = now.tv_sec * 1000000000 + now.tv_nsec; ++ ++ float progress = (float)(current_time - render->animation.start_time) / render->animation.duration; ++ if (progress >= 1.0f) { ++ progress = 1.0f; ++ render->animation.active = false; ++ } else { ++ // Animation still active, need another frame ++ // This will be handled by the main loop checking render_animation_active ++ } ++ ++ // Smoothstep easing ++ return progress * progress * (3.0f - 2.0f * progress); ++} ++ ++bool ++render_animation_active(const struct render *render) ++{ ++ return render->animation.active; ++} ++ + void + render_background(const struct render *render, struct buffer *buf) + { +@@ -276,8 +321,33 @@ render_background(const struct render *render, struct buffer *buf) + max(render->x_margin, + render->y_margin)); + +- render_rounded_rectangle(buf->pix[0], &bg, &border_color, radius, bw, +- 0, 0, buf->width, buf->height); ++ float progress = get_animation_progress((struct render*)render); ++ ++ if (progress < 1.0f) { ++ // Simple scaling by adjusting coordinates ++ int center_x = buf->width / 2; ++ int center_y = buf->height / 2; ++ int scaled_width = buf->width * progress; ++ int scaled_height = buf->height * progress; ++ int x = center_x - scaled_width / 2; ++ int y = center_y - scaled_height / 2; ++ ++ // Clear background first ++ pixman_color_t clear = {0, 0, 0, 0}; ++ pixman_image_fill_rectangles(PIXMAN_OP_SRC, buf->pix[0], &clear, 1, ++ &(pixman_rectangle16_t){0, 0, buf->width, buf->height}); ++ ++ if (scaled_width > 0 && scaled_height > 0) { ++ // Scale both border width and radius proportionally ++ render_rounded_rectangle(buf->pix[0], &bg, &border_color, ++ radius * progress, ++ bw * progress, // Scale border width too ++ x, y, scaled_width, scaled_height); ++ } ++ } else { ++ render_rounded_rectangle(buf->pix[0], &bg, &border_color, radius, bw, ++ 0, 0, buf->width, buf->height); ++ } + } + + static void +@@ -548,6 +618,11 @@ void + render_prompt(struct render *render, struct buffer *buf, + const struct prompt *prompt, const struct matches *matches) + { ++ float progress = get_animation_progress((struct render*)render); ++ if (progress < 1.0f) { ++ // Skip rendering during animation to only show background scaling ++ return; ++ } + struct fcft_font *font = render->font; + assert(font != NULL); + +@@ -1485,6 +1560,11 @@ void + render_match_list(struct render *render, struct buffer *buf, + const struct prompt *prompt, const struct matches *matches) + { ++ float progress = get_animation_progress((struct render*)render); ++ if (progress < 1.0f) { ++ // Skip rendering during animation to only show background scaling ++ return; ++ } + const size_t match_count = matches_get_count(matches); + const size_t selected = matches_get_match_index(matches); + +@@ -1666,6 +1746,9 @@ render_init(const struct config *conf, mtx_t *icon_lock) + } + + LOG_INFO("using %hu render worker threads", render->workers.count); ++ ++ render->animation.active = false; ++ render->animation.duration = 150000000; + + return render; + +diff --git a/render.h b/render.h +index 1e5922e..8259d05 100644 +--- a/render.h ++++ b/render.h +@@ -14,6 +14,9 @@ struct render; + struct render *render_init(const struct config *conf, mtx_t *icon_lock); + void render_destroy(struct render *render); + ++void render_start_expand_animation(struct render *render); ++bool render_animation_active(const struct render *render); ++ + void render_initialize_colors( + struct render *render, const struct config *conf, bool gamma_correct); + +-- +2.50.1 + diff --git a/fuzzel-opening-animation/README.md b/fuzzel-opening-animation/README.md new file mode 100644 index 0000000..9180b48 --- /dev/null +++ b/fuzzel-opening-animation/README.md @@ -0,0 +1,12 @@ +# Fuzzel Expand Animation Patch + +Adds a smooth expand animation when fuzzel opens. + +[Fuzzel](https://codeberg.org/dnkl/fuzzel) is an app launcher and fuzzy finder for Wayland, inspired by rofi(1) and dmenu(1). + +## Usage +1. Clone fuzzel: `git clone https://codeberg.org/dnkl/fuzzel.git` +2. Apply patch: `git apply 0001-fuzzel-animation.patch` +3. Build normally: [Fuzzel Installation](https://codeberg.org/dnkl/fuzzel#installation) + +MIT license diff --git a/niri/config.kdl b/niri/config.kdl index ea26584..da8d10f 100644 --- a/niri/config.kdl +++ b/niri/config.kdl @@ -2,7 +2,7 @@ // "/-" comments out the following node. // Check the wiki for a full description of the configuration: // https://github.com/YaLTeR/niri/wiki/Configuration:-Introduction - +// DOCS: https://variety4me.github.io/niri_docs/ // Input device configuration. // Find the full list of options on the wiki: // https://github.com/YaLTeR/niri/wiki/Configuration:-Input @@ -201,44 +201,6 @@ layout { // inactive-gradient from="#505050" to="#808080" angle=45 relative-to="workspace-view" } - // You can enable drop shadows for windows. - shadow { - on - // Uncomment the next line to enable shadows. - // on - - // By default, the shadow draws only around its window, and not behind it. - // Uncomment this setting to make the shadow draw behind its window. - // - // Note that niri has no way of knowing about the CSD window corner - // radius. It has to assume that windows have square corners, leading to - // shadow artifacts inside the CSD rounded corners. This setting fixes - // those artifacts. - // - // However, instead you may want to set prefer-no-csd and/or - // geometry-corner-radius. Then, niri will know the corner radius and - // draw the shadow correctly, without having to draw it behind the - // window. These will also remove client-side shadows if the window - // draws any. - // - // draw-behind-window true - - // You can change how shadows look. The values below are in logical - // pixels and match the CSS box-shadow properties. - - // Softness controls the shadow blur radius. - softness 30 - - // Spread expands the shadow. - spread 5 - - // Offset moves the shadow relative to the window. - offset x=0 y=5 - - // You can also change the shadow color and opacity. - color "#0007" - } - // Struts shrink the area occupied by windows, similarly to layer-shell panels. // You can think of them as a kind of outer gaps. They are set in logical pixels. // Left and right struts will cause the next window to the side to always be visible. @@ -271,7 +233,9 @@ spawn-at-startup "wl-clip-persist" "--clipboard" "regular" // Clipboard history spawn-at-startup "wl-paste" "--type" "text" "--watch" "cliphist" "store" -//spawn-at-startup "wl-paste" "--type" "image" "--watch" "cliphist" "store" +spawn-at-startup "wl-paste" "--type" "image" "--watch" "cliphist" "store" + +spawn-at-startup "arch_news.sh" // Uncomment this line to ask the clients to omit their client-side decorations if possible. // If the client will specifically ask for CSD, the request will be honored. // Additionally, clients will be informed that they are tiled, removing some client-side rounded corners. @@ -298,59 +262,36 @@ animations { // slowdown 3.0 } +// https://variety4me.github.io/niri_docs/Configuration-Switch-Events/ +switch-events { + lid-close { spawn "waylock"; } + lid-open { spawn "brightnessctl" "s" "50%"; } +} + // Window rules let you adjust behavior for individual windows. // Find more information on the wiki: // https://github.com/YaLTeR/niri/wiki/Configuration:-Window-Rules -// Work around WezTerm's initial configure bug -// by setting an empty default-column-width. -window-rule { - // This regular expression is intentionally made as specific as possible, - // since this is the default config, and we want no false positives. - // You can get away with just app-id="wezterm" if you want. - match app-id=r#"^org\.wezfurlong\.wezterm$"# - default-column-width {} -} - // Open the Firefox picture-in-picture player as floating by default. window-rule { // This app-id regular expression will work for both: // - host Firefox (app-id is "firefox") // - Flatpak Firefox (app-id is "org.mozilla.firefox") - match app-id=r#"firefox$"# title="^Picture-in-Picture$" + match app-id=r#"zen$"# title="^Picture-in-Picture$" open-floating true } window-rule { - match app-id="zen" +// match app-id="zen" +// match app-id="obsidian" +// open-maximized true +} + +window-rule { open-maximized true -} -// set class to open floating windows "alacritty --class floating -e bluetuith" -window-rule { - match app-id="floating" - default-column-width { proportion 0.5; } - open-on-output "current" - open-floating true -} - - -// Example: block out two password managers from screen capture. -// (This example rule is commented out with a "/-" in front.) -/-window-rule { - match app-id=r#"^org\.keepassxc\.KeePassXC$"# - match app-id=r#"^org\.gnome\.World\.Secrets$"# - - block-out-from "screen-capture" - - // Use this instead if you want them visible on third-party screenshot tools. - // block-out-from "screencast" -} - -// Example: enable rounded corners for all windows. -// (This example rule is commented out with a "/-" in front.) -/-window-rule { -// geometry-corner-radius 12 - clip-to-geometry true + match app-id=r#"^zen$"# + match app-id=r#"^obsidian$"# + match app-id=r#"^org\.freedesktop\.Xwayland$"# } binds { @@ -370,6 +311,7 @@ binds { // Suggested binds for running programs: terminal, app launcher, screen locker. Mod+T hotkey-overlay-title="Open a Terminal: alacritty" { spawn "alacritty"; } + Mod+Return hotkey-overlay-title="Open a Terminal: alacritty" { spawn "alacritty"; } Mod+D hotkey-overlay-title="Run an Application: fuzzel" { spawn "fuzzel"; } Super+Alt+L hotkey-overlay-title="Lock the Screen: swaylock" { spawn "waylock"; } diff --git a/waybar/.gitignore b/waybar/.gitignore new file mode 100644 index 0000000..36445e5 --- /dev/null +++ b/waybar/.gitignore @@ -0,0 +1 @@ +/temp diff --git a/waybar/config.jsonc b/waybar/config.jsonc index 22e3b66..6e754f8 100644 --- a/waybar/config.jsonc +++ b/waybar/config.jsonc @@ -11,7 +11,6 @@ ], "modules-center": ["niri/window"], "modules-right": [ - "network", "battery", "bluetooth", "group/pulseaudio-wrapper", @@ -72,13 +71,13 @@ }, "custom/reboot": { "format": "󰜉", - "on-click": "zenity --question --text='Are you sure you want to reboot?' --icon-name='system-reboot' --title='Reboot System' && sleep 1 && systemctl reboot", + "on-click": "zenity --question --text='Are you sure you want to reboot?' --icon-name='system-reboot' --title='Reboot System' && sleep 1 && systemctl reboot --force", "tooltip": true, "tooltip-format": "Reboot" }, "custom/power": { "format": "󰐥", - "on-click": "zenity --question --text='Are you sure you want to power off?' --icon-name='system-shutdown' --title='Power Off System' && sleep 1 && loginctl poweroff", + "on-click": "zenity --question --text='Are you sure you want to power off?' --icon-name='system-shutdown' --title='Power Off System' && sleep 1 && systemctl poweroff --force", "tooltip": true, "tooltip-format": "Power Off" }, @@ -188,7 +187,7 @@ }, "clock": { "interval": 1, - "format": "󰃰 {:%a %H:%M}", + "format": "󰃰 {:%d.%m %a %H:%M}", "tooltip": true, "tooltip-format": "{:L%A, %d-%m-%Y}" },