From 4ec06e5a996cc8c138553399b739a65bd53906aa Mon Sep 17 00:00:00 2001 From: Chintan Patel <216989679+Chintanpatel24@users.noreply.github.com> Date: Thu, 17 Sep 2026 15:59:52 +0530 Subject: [PATCH] fix(bar): fix bar thickness reduction, elevate CSS provider priority, and add widget auto-scaling --- agility-shell | 10 ++++++++++ bar.py | 37 +++++++++++++++++++++++++---------- bar_widgets/base.py | 24 +++++++++++++++++++++++ bar_widgets/dock/__init__.py | 14 +++++++++++++ bar_widgets/dock/dock_item.py | 17 ++++++++++++++++ bar_widgets/quick_settings.py | 19 ++++++++++++++++-- bar_widgets/workspaces.py | 32 +++++++++++++++++++++++++----- bin/agl | 12 +++++++++++- main.py | 11 +++++++++++ scripts/install.sh | 16 +++++++++++++++ snippets/icon.py | 4 ++++ style/bar.css | 14 ++++++------- 12 files changed, 185 insertions(+), 25 deletions(-) diff --git a/agility-shell b/agility-shell index 962befc..32ca6f5 100755 --- a/agility-shell +++ b/agility-shell @@ -52,6 +52,16 @@ if [[ -f "$SELF_DIR/main.py" && -f "$SELF_DIR/bar.py" ]]; then else PYTHON_EXEC="python3" fi +elif [[ -d "${XDG_DATA_HOME:-$HOME/.local/share}/agility-shell" && -f "${XDG_DATA_HOME:-$HOME/.local/share}/agility-shell/main.py" ]]; then + # User data directory installation (non-root) + SOURCE_DIR="${XDG_DATA_HOME:-$HOME/.local/share}/agility-shell" + if [[ -x "$SOURCE_DIR/venv/bin/python3" ]]; then + PYTHON_EXEC="$SOURCE_DIR/venv/bin/python3" + elif [[ -x "$SYSTEM_VENV/bin/python3" ]]; then + PYTHON_EXEC="$SYSTEM_VENV/bin/python3" + else + PYTHON_EXEC="python3" + fi elif [[ -d "$SYSTEM_DATA" && -f "$SYSTEM_DATA/main.py" ]]; then # Standard system-wide FHS installation SOURCE_DIR="$SYSTEM_DATA" diff --git a/bar.py b/bar.py index c6f212f..2fff910 100644 --- a/bar.py +++ b/bar.py @@ -167,23 +167,24 @@ def update_bar_height_css(height: int): global _bar_height_provider v_padding, widget_h, scale_sz = get_bar_dimensions(height) dot_pad = max(2, (widget_h - 6) // 2) - ws_size = max(18, widget_h - 4) + ws_size = max(16, widget_h - 4) ws_margin = max(1, (widget_h - ws_size) // 2) - ws_pad = max(2, (widget_h - 20) // 2) - dock_pad = max(0, (widget_h - 24) // 2) + ws_pad = max(2, (widget_h - 18) // 2) + dock_pad = max(0, (widget_h - 22) // 2) + dock_icon_sz = 16 if height <= 28 else (18 if height <= 34 else (20 if height <= 40 else (22 if height <= 44 else 24))) css = f""" - .bar {{ + box.bar, CenterBox.bar, .bar {{ padding-top: {v_padding}px; padding-bottom: {v_padding}px; }} - .bar-button {{ + box.bar-button, .bar-button {{ min-height: {widget_h}px; }} - .draggable-section {{ + box.draggable-section, .draggable-section {{ min-height: {widget_h}px; }} - .draggable-section.edit-mode {{ + box.draggable-section.edit-mode, .draggable-section.edit-mode {{ min-width: {widget_h}px; }} .drop-placeholder {{ @@ -201,10 +202,19 @@ def update_bar_height_css(height: int): margin-bottom: {ws_margin}px; }} .workspace {{ - padding: {ws_pad}px 7px; + padding-top: {ws_pad}px; + padding-bottom: {ws_pad}px; + padding-left: 6px; + padding-right: 6px; }} .dock-item {{ - padding: {dock_pad}px 6px; + padding-top: {dock_pad}px; + padding-bottom: {dock_pad}px; + padding-left: 4px; + padding-right: 4px; + }} + .dock-item .icon {{ + min-height: {dock_icon_sz}px; }} """ if _bar_height_provider is None: @@ -214,7 +224,7 @@ def update_bar_height_css(height: int): Gtk.StyleContext.add_provider_for_screen( screen, _bar_height_provider, - Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION + 10, + Gtk.STYLE_PROVIDER_PRIORITY_USER + 50, ) try: _bar_height_provider.load_from_data(css.encode("utf-8")) @@ -1775,7 +1785,14 @@ def apply_bar_height(self, height: int, widget_h: int = None, scale_sz: int = No for section in self.sections.values(): for child in section.get_children(): self._update_child_bar_height(child, height, widget_h, scale_sz) + section.queue_resize() + if hasattr(self, "_centerbox"): + self._centerbox.reset_style() + self._centerbox.queue_resize() self.queue_resize() + self.resize(1, 1) + if hasattr(self, "_blur_ctx") and self._blur_ctx: + GLib.timeout_add(250, self._update_blur_region) def _update_child_bar_height(self, wrapper, height: int, widget_h: int, scale_sz: int): def _apply_to_widget(w): diff --git a/bar_widgets/base.py b/bar_widgets/base.py index edd340f..aef681b 100644 --- a/bar_widgets/base.py +++ b/bar_widgets/base.py @@ -65,6 +65,30 @@ def _update_label(self, text: str): def _update_icon(self, icon_name: str): self._icon.set_property("icon-name", icon_name) + def apply_bar_height(self, height: int): + if height <= 28: + icon_sz = 14 + elif height <= 34: + icon_sz = 16 + else: + icon_sz = 18 + if hasattr(self, "_icon") and self._icon is not None: + if hasattr(self._icon, "set_size"): + try: + self._icon.set_size(icon_sz) + except Exception: + pass + elif hasattr(self._icon, "set_pixel_size"): + try: + self._icon.set_pixel_size(icon_sz) + except Exception: + pass + elif hasattr(self._icon, "set_size_request"): + try: + self._icon.set_size_request(icon_sz, icon_sz) + except Exception: + pass + class ProgressButton(Box): VARIANTS = [VARIANT_ICON, VARIANT_SCALE, VARIANT_ICON_LABEL, VARIANT_SCALE_LABEL] diff --git a/bar_widgets/dock/__init__.py b/bar_widgets/dock/__init__.py index beda885..4cb13ff 100644 --- a/bar_widgets/dock/__init__.py +++ b/bar_widgets/dock/__init__.py @@ -22,6 +22,7 @@ def __init__(self, monitor_id: int, vertical: bool = False, variant="", **kwargs self._vertical = vertical self._monitor_output = get_connector_from_monitor_id(monitor_id) self._state = DockState(user_options) + self._current_bar_height = getattr(user_options.settings, "bar_height", 36) super().__init__( style_classes=["dock"], @@ -93,6 +94,8 @@ def _rebuild(self) -> None: on_pin_toggle=self._on_pin_toggle, ) item._icon_container.add_style_class("pinned") + if hasattr(item, "apply_bar_height"): + item.apply_bar_height(self._current_bar_height) self._pinned_box.add(item) # item._setup_drag() item.show_all() @@ -130,6 +133,8 @@ def _rebuild(self) -> None: on_workspace_move=self._on_workspace_move, on_pin_toggle=self._on_pin_toggle, ) + if hasattr(item, "apply_bar_height"): + item.apply_bar_height(self._current_bar_height) self._workspace_box.add(item) item.show_all() @@ -137,6 +142,15 @@ def _rebuild(self) -> None: self._pinned_container.set_visible(len(pinned_items) > 0) self._update_pill() + def apply_bar_height(self, height: int) -> None: + self._current_bar_height = height + for item in self._pinned_box.get_children(): + if hasattr(item, "apply_bar_height"): + item.apply_bar_height(height) + for item in self._workspace_box.get_children(): + if hasattr(item, "apply_bar_height"): + item.apply_bar_height(height) + def _update_pill(self, _retries: int = 0) -> None: active = wm.active_window if not active: diff --git a/bar_widgets/dock/dock_item.py b/bar_widgets/dock/dock_item.py index ede1bdf..95f4823 100644 --- a/bar_widgets/dock/dock_item.py +++ b/bar_widgets/dock/dock_item.py @@ -84,6 +84,23 @@ def _on_leave(self, w, event): if event.detail != Gdk.NotifyType.INFERIOR: self._icon_container.remove_style_class("hovered") + def apply_bar_height(self, height: int): + if height <= 28: + sz = 16 + elif height <= 34: + sz = 18 + elif height <= 40: + sz = 20 + elif height <= 44: + sz = 22 + else: + sz = 24 + if hasattr(self, "_icon") and self._icon: + try: + self._icon.set_pixel_size(sz) + except Exception: + pass + def _resolve_icon(self) -> str: return ( get_app_icon_name(self.app_id) diff --git a/bar_widgets/quick_settings.py b/bar_widgets/quick_settings.py index 7fda491..0dcbde0 100644 --- a/bar_widgets/quick_settings.py +++ b/bar_widgets/quick_settings.py @@ -13,10 +13,12 @@ def __init__(self, monitor_id, vertical, variant="single", **kwargs): self._bluetooth_icon = BluetoothIcon(16) self._scroll_accumulator = 0.0 + self._single_icon = Icon(icon_name="sliders-horizontal-duotone", icon_size=16) if variant == "single" else None + inner = Box( style_classes=["bar-button"], spacing=4, - children=[Icon(icon_name="sliders-horizontal-duotone")] if variant == "single" else [ + children=[self._single_icon] if variant == "single" else [ NetworkIcon(16), self._bluetooth_icon, VolumeIcon(16), @@ -63,4 +65,17 @@ def _adjust(self, direction: int): def _on_bt_state_changed(self, obj, _): self._bluetooth_icon.set_visible(obj.enabled) def _on_recorder_changed(self, obj, _): - self._record_icon.set_visible(obj.active) \ No newline at end of file + self._record_icon.set_visible(obj.active) + + def apply_bar_height(self, height: int): + sz = 14 if height <= 28 else (16 if height <= 34 else 18) + if hasattr(self, "_single_icon") and self._single_icon: + try: + self._single_icon.set_size(sz) + except Exception: + pass + if hasattr(self, "_bluetooth_icon") and self._bluetooth_icon: + try: + self._bluetooth_icon.set_pixel_size(sz) + except Exception: + pass \ No newline at end of file diff --git a/bar_widgets/workspaces.py b/bar_widgets/workspaces.py index 1f5aae5..39111e9 100644 --- a/bar_widgets/workspaces.py +++ b/bar_widgets/workspaces.py @@ -20,18 +20,19 @@ PILL_BEZIER_MORPH = (0.4, 0.0, 1.0, 1.0) class WorkspaceButton(EventBox): - def __init__(self, workspace, windows, variant): + def __init__(self, workspace, windows, variant, icon_size: int = 16): self.variant = variant self.workspace = workspace + self._icon_size = icon_size self.icon_map: dict[int, Image] = {} - self._icon_box = Box(spacing=8) + self._icon_box = Box(spacing=6) for w in windows: if w.workspace_id == workspace.id: icon = Image( css_classes=["icon"], icon_name=self._get_icon(w), - icon_size=20, + icon_size=self._icon_size, ) self.icon_map[w.id] = icon self._icon_box.add(icon) @@ -40,12 +41,28 @@ def __init__(self, workspace, windows, variant): child=Box( style_classes=["workspace"] + (["active"] if workspace.is_active else []), orientation="v", - spacing=8, + spacing=6, children=[self._icon_box], ), ) self.connect("button-release-event", self._on_click) + def apply_bar_height(self, height: int): + if height <= 28: + sz = 14 + elif height <= 34: + sz = 16 + elif height <= 40: + sz = 18 + else: + sz = 20 + self._icon_size = sz + for icon in self.icon_map.values(): + try: + icon.set_pixel_size(sz) + except Exception: + pass + def _on_click(self, _, event): if edit_mode.edit_mode: return False @@ -73,7 +90,7 @@ def add_window(self, window, all_windows: list): icon = Image( css_classes=["icon"], icon_name=self._get_icon(window), - icon_size=20, + icon_size=getattr(self, "_icon_size", 16), ) self.icon_map[window.id] = icon @@ -549,3 +566,8 @@ def _scroll(self, direction: str): else: next_idx = (current_idx + 1) % len(monitor_workspaces) monitor_workspaces[next_idx].switch_to() + + def apply_bar_height(self, height: int): + for btn in self._ws_buttons.values(): + if hasattr(btn, "apply_bar_height"): + btn.apply_bar_height(height) diff --git a/bin/agl b/bin/agl index ac4896c..45ec3bf 100755 --- a/bin/agl +++ b/bin/agl @@ -416,7 +416,17 @@ cmd_bar() { local val="${1:-}" if [[ -n "$val" ]]; then if command -v fabric-cli &>/dev/null; then - fabric-cli exec agility-shell "bar_manager.apply_bar_height($val)" 2>/dev/null || true + fabric-cli exec agility-shell " +import services.singletons as s, user_options +try: + bm = s.bar_manager + if bm and hasattr(bm, 'apply_bar_height'): + bm.apply_bar_height(int($val)) + user_options.user_options.settings.bar_height = int($val) + user_options.user_options.save() +except Exception: + pass +" 2>/dev/null || true fi python3 -c " import json, os diff --git a/main.py b/main.py index 74f5f92..1f8957a 100644 --- a/main.py +++ b/main.py @@ -48,6 +48,17 @@ def seed_user_environment(): except Exception: pass + # Clean up stale legacy component stylesheets in user style dir that shadow updated system stylesheets + # Keep user customization files: borders, fonts, colors, agility-shell-colors, or custom* + whitelist = {"borders.css", "fonts.css", "colors.css", "agility-shell-colors.css", "custom.css"} + if os.path.isdir(style_dir): + for fname in os.listdir(style_dir): + if fname.endswith(".css") and fname not in whitelist and not fname.startswith("custom"): + try: + os.remove(os.path.join(style_dir, fname)) + except Exception: + pass + # Migrate existing widget settings if needed user_settings = os.path.join(user_dir, "widget_settings.json") if not os.path.exists(user_settings): diff --git a/scripts/install.sh b/scripts/install.sh index 1fc1a65..acd27e0 100755 --- a/scripts/install.sh +++ b/scripts/install.sh @@ -475,6 +475,22 @@ seed_user_configuration() { fi done + # Prune stale legacy component stylesheets in user style dir that shadow updated system stylesheets + for f in "$USER_CONFIG/style"/*.css; do + [[ -f "$f" ]] || continue + local fname + fname="$(basename "$f")" + case "$fname" in + borders.css|fonts.css|colors.css|agility-shell-colors.css|custom*.css) + ;; + *) + if [[ -f "$src_data/style/$fname" ]]; then + rm -f "$f" + fi + ;; + esac + done + # Seed baseline niri.kdl if not present if [[ -f "$src_data/config/niri.kdl" ]]; then mkdir -p "$USER_CONFIG/config" diff --git a/snippets/icon.py b/snippets/icon.py index e45fca2..75a710c 100644 --- a/snippets/icon.py +++ b/snippets/icon.py @@ -69,6 +69,10 @@ def icon_name(self, value: str): self._icon_name = value self.set_from_file(get_svg_path(value)) + def set_size(self, size: int): + self.set_size_request(size, size) + self.queue_draw() + def do_finalize_handle(self): if not self._handle: return diff --git a/style/bar.css b/style/bar.css index 8682e6e..35fc044 100644 --- a/style/bar.css +++ b/style/bar.css @@ -2,7 +2,7 @@ .bar { background-color: var(--background); - padding: 4px; + padding: 2px 4px; } @keyframes bar-slide-in-top { @@ -334,8 +334,8 @@ .bar-button { border-radius: apply(radius-m); - padding: 0px 10px; - min-height: 28px; + padding: 0px 8px; + min-height: 20px; } .bar-button.variant-scale-label { @@ -418,11 +418,11 @@ .draggable-section { transition: 0.3s ease; - min-height: 28px; + min-height: 20px; } .draggable-section.edit-mode { - min-width: 28px; + min-width: 20px; } .draggable-section.center { @@ -467,8 +467,8 @@ } .drop-placeholder { - min-width: 28px; - min-height: 28px; + min-width: 20px; + min-height: 20px; border-radius: apply(radius-m); background: alpha(var(--on_surface), 0.1); transition: all 0.3s ease;