From d7a19bc1b70fdac7b837b0b2db8d80a58a051f95 Mon Sep 17 00:00:00 2001 From: Atif Date: Thu, 12 Jun 2025 00:11:20 +0600 Subject: [PATCH 1/7] added option to auto generate layout icons --- .../widgets/komorebi/active_layout.py | 5 + src/core/widgets/komorebi/active_layout.py | 225 +++++++++++++++--- 2 files changed, 196 insertions(+), 34 deletions(-) diff --git a/src/core/validation/widgets/komorebi/active_layout.py b/src/core/validation/widgets/komorebi/active_layout.py index afc626bd..89773f81 100644 --- a/src/core/validation/widgets/komorebi/active_layout.py +++ b/src/core/validation/widgets/komorebi/active_layout.py @@ -34,6 +34,7 @@ 'enabled': True, 'type': 'fadeInOut', 'duration': 200 + "generate_layout_icons": False, }, 'callbacks': { 'on_left': 'next_layout', @@ -179,6 +180,10 @@ }, 'default': DEFAULTS['layout_menu'] }, + "generate_layout_icons": { + "type": "boolean", + "default": DEFAULTS["generate_layout_icons"], + }, 'container_padding': { 'type': 'dict', 'default': DEFAULTS['container_padding'], diff --git a/src/core/widgets/komorebi/active_layout.py b/src/core/widgets/komorebi/active_layout.py index 7eeeb884..4be3fad3 100644 --- a/src/core/widgets/komorebi/active_layout.py +++ b/src/core/widgets/komorebi/active_layout.py @@ -1,16 +1,18 @@ import logging from collections import deque -from PyQt6.QtGui import QCursor -from PyQt6.QtWidgets import QWidget, QLabel, QHBoxLayout, QVBoxLayout, QFrame, QSizePolicy -from PyQt6.QtCore import Qt, pyqtSignal -from core.utils.win32.utilities import get_monitor_hwnd -from core.event_service import EventService + +from PyQt6.QtCore import QPointF, QRectF, QSize, Qt, pyqtSignal +from PyQt6.QtGui import QCursor, QPainter +from PyQt6.QtWidgets import QFrame, QHBoxLayout, QLabel, QSizePolicy, QVBoxLayout, QWidget + from core.event_enums import KomorebiEvent -from core.widgets.base import BaseWidget +from core.event_service import EventService from core.utils.komorebi.client import KomorebiClient -from core.validation.widgets.komorebi.active_layout import VALIDATION_SCHEMA +from core.utils.utilities import PopupWidget, add_shadow from core.utils.widgets.animation_manager import AnimationManager -from core.utils.utilities import add_shadow, PopupWidget +from core.utils.win32.utilities import get_monitor_hwnd +from core.validation.widgets.komorebi.active_layout import VALIDATION_SCHEMA +from core.widgets.base import BaseWidget try: from core.utils.komorebi.event_listener import KomorebiEventListener @@ -27,7 +29,7 @@ "VerticalStack": "vertical-stack", "HorizontalStack": "horizontal-stack", "UltrawideVerticalStack": "ultrawide-vertical-stack", - "RightMainVerticalStack": "right-main-vertical-stack" + "RightMainVerticalStack": "right-main-vertical-stack", } layout_snake_case = { "BSP": "bsp", @@ -38,9 +40,141 @@ "VerticalStack": "vertical_stack", "HorizontalStack": "horizontal_stack", "UltrawideVerticalStack": "ultrawide_vertical_stack", - "RightMainVerticalStack": "right_main_vertical_stack" + "RightMainVerticalStack": "right_main_vertical_stack", + "Monocle": "monocle", + "Maximised": "maximised", + "Paused": "paused", } + +class LayoutIconWidget(QWidget): + def __init__( + self, + layout_name: str = "bsp", + alignment: Qt.AlignmentFlag = Qt.AlignmentFlag.AlignCenter, + ): + super().__init__() + self.layout_name = layout_name + self._alignment = alignment + + def sizeHint(self): + size = self.font().pixelSize() + return QSize(size, size) + + def setAlignment(self, alignment: Qt.AlignmentFlag): + self._alignment = alignment + self.updateGeometry() + self.update() + + def paintEvent(self, a0): + painter = QPainter(self) + painter.setRenderHint(QPainter.RenderHint.Antialiasing) + + size = self.font().pixelSize() + width, height = size, size + stroke_width = 1 + + rect = self.rect() + icon_rect = QRectF(0, 0, width, height) + + if self._alignment & Qt.AlignmentFlag.AlignHCenter: + icon_rect.moveLeft((rect.width() - width) / 2) + elif self._alignment & Qt.AlignmentFlag.AlignRight: + icon_rect.moveLeft(rect.width() - width) + # else: default is AlignLeft, so no need to move + + if self._alignment & Qt.AlignmentFlag.AlignVCenter: + icon_rect.moveTop((rect.height() - height) / 2) + elif self._alignment & Qt.AlignmentFlag.AlignBottom: + icon_rect.moveTop(rect.height() - height) + # else: default is AlignTop, so no need to move + + r = (icon_rect.width() / 2) - stroke_width + c = icon_rect.center() + icon_rect = icon_rect.adjusted(stroke_width, stroke_width, -stroke_width, -stroke_width) + rounding = icon_rect.width() * 0.1 + painter.drawRoundedRect(icon_rect, rounding, rounding) + + self._draw_icon(painter, icon_rect, r, c) + painter.end() + + def _draw_icon( + self, + painter: QPainter, + icon_rect: QRectF, + r: float, + c: QPointF, + ): + # helper functions to draw lines and vectors + def vec(dx, dy): + return QPointF(dx, dy) + + def line(start, end): + painter.drawLine(start, end) + + # draw layout icons + if self.layout_name == "bsp": + line(c - vec(0, r), c + vec(0, r)) + line(c, c + vec(r, 0)) + line(c + vec(r / 2, 0), c + vec(r / 2, r)) + elif self.layout_name == "columns": + line(c - vec(r / 2, r), c + vec(-r / 2, r)) + line(c - vec(0, r), c + vec(0, r)) + line(c - vec(-r / 2, r), c + vec(r / 2, r)) + elif self.layout_name == "rows": + line(c - vec(r, r / 2), c + vec(r, -r / 2)) + line(c - vec(r, 0), c + vec(r, 0)) + line(c - vec(r, -r / 2), c + vec(r, r / 2)) + elif self.layout_name == "vertical_stack": + line(c - vec(0, r), c + vec(0, r)) + line(c, c + vec(r, 0)) + elif self.layout_name == "right_main_vertical_stack": + line(c - vec(0, r), c + vec(0, r)) + line(c - vec(r, 0), c) + elif self.layout_name == "horizontal_stack": + line(c - vec(r, 0), c + vec(r, 0)) + line(c, c + vec(0, r)) + elif self.layout_name == "ultrawide_vertical_stack": + line(c - vec(r / 2, r), c + vec(-r / 2, r)) + line(c + vec(r / 2, 0), c + vec(r, 0)) + line(c - vec(-r / 2, r), c + vec(r / 2, r)) + elif self.layout_name == "grid": + line(c - vec(r, 0), c + vec(r, 0)) + line(c - vec(0, r), c + vec(0, r)) + elif self.layout_name == "scrolling": + line(c - vec(r / 2, r), c + vec(-r / 2, r)) + line(c - vec(0, r), c + vec(0, r)) + line(c - vec(-r / 2, r), c + vec(r / 2, r)) + elif self.layout_name == "monocle" or self.layout_name == "maximised": + pass + elif self.layout_name == "paused": + rect_left = QRectF(icon_rect) + rect_right = QRectF(rect_left) + + rect_left.setWidth(icon_rect.width() * 0.25) + rect_left.setHeight(icon_rect.height() * 0.8) + rect_right.setWidth(rect_left.width()) + rect_right.setHeight(rect_left.height()) + + rect_left.moveTopLeft(icon_rect.topLeft() + vec(icon_rect.width() * 0.2, icon_rect.width() * 0.1)) + + rect_right.moveTopLeft( + icon_rect.topLeft() + + vec( + icon_rect.width() * 0.55, + icon_rect.width() * 0.1, + ) + ) + + color = self.palette().color(self.foregroundRole()) + painter.fillRect(rect_left, color) + painter.fillRect(rect_right, color) + else: + line(c - vec(0, r), c + vec(0, r)) + line(c + vec(0, r / 2), c + vec(r, r / 2)) + line(c - vec(0, r / 3), c - vec(r, r / 3)) + + class ActiveLayoutWidget(BaseWidget): k_signal_connect = pyqtSignal(dict) k_signal_disconnect = pyqtSignal() @@ -56,18 +190,20 @@ def __init__( layouts: list[str], layout_icons: dict[str, str], layout_menu: dict[str, str], + generate_layout_icons: bool, hide_if_offline: bool, container_padding: dict, animation: dict[str, str], callbacks: dict[str, str], label_shadow: dict = None, - container_shadow: dict = None + container_shadow: dict = None, ): super().__init__(class_name="komorebi-active-layout") self._label = label self._layout_icons = layout_icons self._layout_menu = layout_menu self._layouts_config = layouts + self._generate_layout_icons = generate_layout_icons self._padding = container_padding self._label_shadow = label_shadow self._container_shadow = container_shadow @@ -80,6 +216,8 @@ def __init__( self._focused_workspace = {} # Set the cursor to be a pointer when hovering over the button self.setCursor(QCursor(Qt.CursorShape.PointingHandCursor)) + self._active_layout_icon = LayoutIconWidget() + self._active_layout_icon.setProperty("class", "icon") self._active_layout_text = QLabel() self._active_layout_text.setProperty("class", "label") self._active_layout_text.setAlignment(Qt.AlignmentFlag.AlignCenter) @@ -96,7 +234,9 @@ def __init__( add_shadow(self._widget_container, self._container_shadow) # Add the container to the main widget layout self.widget_layout.addWidget(self._widget_container) - + + if self._generate_layout_icons: + self._widget_container_layout.addWidget(self._active_layout_icon) self._widget_container_layout.addWidget(self._active_layout_text) self.callback_left = callbacks['on_left'] @@ -124,7 +264,7 @@ def _toggle_layout_menu(self): if self._animation['enabled']: AnimationManager.animate(self, self._animation['type'], self._animation['duration']) self._show_layout_menu() - + def _show_layout_menu(self): self._menu = PopupWidget( self, @@ -146,10 +286,12 @@ def create_menu_item(icon, text, click_handler): item_layout.setContentsMargins(0, 0, 0, 0) if self._layout_menu['show_layout_icons']: - icon_label = QLabel(icon) - icon_label.setProperty("class", "menu-item-icon") + icon_label = QLabel(icon) if isinstance(icon, str) else icon + icon_label.setAlignment(Qt.AlignmentFlag.AlignLeft | Qt.AlignmentFlag.AlignVCenter) icon_label.setSizePolicy(QSizePolicy.Policy.Fixed, QSizePolicy.Policy.Fixed) + + icon_label.setProperty("class", "menu-item-icon") item_layout.addWidget(icon_label) text_label = QLabel(text) @@ -163,10 +305,15 @@ def create_menu_item(icon, text, click_handler): return item for layout in self._layouts_config: - icon = self._layout_icons[layout] + if self._generate_layout_icons: + icon = LayoutIconWidget(layout) + else: + icon = self._layout_icons[layout] text = layout.replace('_', ' ').title() + def handler(event, l=layout): self._on_layout_menu_selected(l) + main_layout.addWidget(create_menu_item(icon, text, handler)) self._menu._add_separator(main_layout) @@ -175,23 +322,31 @@ def make_toggle_handler(func): def handler(event): func() self._menu.hide() + return handler - toggle_icons = { - "Toggle Tiling": self._layout_icons["tiling"], - "Toggle Monocle": self._layout_icons["monocle"], - "Toggle Pause": self._layout_icons["paused"] - } + if self._generate_layout_icons: + toggle_icons = { + "Toggle Tiling": LayoutIconWidget("tiling"), + "Toggle Monocle": LayoutIconWidget("monocle"), + "Toggle Pause": LayoutIconWidget("paused"), + } + else: + toggle_icons = { + "Toggle Tiling": self._layout_icons["tiling"], + "Toggle Monocle": self._layout_icons["monocle"], + "Toggle Pause": self._layout_icons["paused"], + } toggle_actions = [ ("Toggle Tiling", lambda: self._komorebic.toggle("tiling")), ("Toggle Monocle", lambda: self._komorebic.toggle("monocle")), - ("Toggle Pause", lambda: self._komorebic.toggle("pause")) + ("Toggle Pause", lambda: self._komorebic.toggle("pause")), ] for label, func in toggle_actions: main_layout.addWidget( create_menu_item( - toggle_icons.get(label, ""), - label, + toggle_icons.get(label, ""), + label, make_toggle_handler(func) ) ) @@ -229,14 +384,14 @@ def _next_layout(self): self.change_layout(self._layouts[0]) if self._animation['enabled']: AnimationManager.animate(self, self._animation['type'], self._animation['duration']) - + def _prev_layout(self): if self._is_shift_layout_allowed(): self._layouts.rotate(-1) self.change_layout(self._layouts[0]) if self._animation['enabled']: AnimationManager.animate(self, self._animation['type'], self._animation['duration']) - + def _is_shift_layout_allowed(self): return not bool( not self._focused_workspace.get('tile', False) or @@ -253,7 +408,7 @@ def _register_signals_and_events(self): KomorebiEvent.TogglePause, KomorebiEvent.ToggleTiling, KomorebiEvent.ToggleMonocle, - KomorebiEvent.ToggleMaximise + KomorebiEvent.ToggleMaximise, ] self.k_signal_connect.connect(self._on_komorebi_connect_event) @@ -261,10 +416,10 @@ def _register_signals_and_events(self): self.k_signal_layout_change.connect(self._on_komorebi_layout_change_event) self.k_signal_update.connect(self._on_komorebi_layout_change_event) - self._event_service.register_event(KomorebiEvent.KomorebiConnect, self.k_signal_connect) + self._event_service.register_event(KomorebiEvent.KomorebiConnect, self.k_signal_connect) self._event_service.register_event(KomorebiEvent.KomorebiDisconnect, self.k_signal_disconnect) self._event_service.register_event(KomorebiEvent.KomorebiUpdate, self.k_signal_update) - + for event_type in active_layout_change_event_watchlist: self._event_service.register_event(event_type, self.k_signal_layout_change) @@ -272,7 +427,7 @@ def _on_komorebi_connect_event(self, state: dict) -> None: self._update_active_layout(state, is_connect_event=True) if self.isHidden(): self.show() - + def _on_komorebi_layout_change_event(self, _event: dict, state: dict) -> None: self._update_active_layout(state) @@ -297,9 +452,11 @@ def _update_active_layout(self, state: dict, is_connect_event=False): while self._layouts[0] != conn_layout_cmd: self._layouts.rotate(1) - self._active_layout_text.setText( - self._label.replace("{icon}", layout_icon).replace("{layout_name}", layout_name) - ) + if self._generate_layout_icons: + self._active_layout_icon.layout_name = layout_snake_case.get(layout_name, "unknown layout") + self._active_layout_icon.update() + + self._active_layout_text.setText(self._label.replace("{icon}", layout_icon).replace("{layout_name}", layout_name)) if self._active_layout_text.isHidden(): self.show() @@ -335,4 +492,4 @@ def _update_komorebi_state(self, komorebi_state: dict): self._komorebi_workspaces = self._komorebic.get_workspaces(self._komorebi_screen) return True except TypeError: - return False \ No newline at end of file + return False From fc1ddb973e4b0c62983a5fa0a51568c618ca55fc Mon Sep 17 00:00:00 2001 From: Atif Date: Thu, 12 Jun 2025 00:29:11 +0600 Subject: [PATCH 2/7] quickfix validation config --- src/core/validation/widgets/komorebi/active_layout.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/validation/widgets/komorebi/active_layout.py b/src/core/validation/widgets/komorebi/active_layout.py index 89773f81..1702dc9c 100644 --- a/src/core/validation/widgets/komorebi/active_layout.py +++ b/src/core/validation/widgets/komorebi/active_layout.py @@ -29,12 +29,12 @@ 'offset_left': 0, 'show_layout_icons': True, }, + "generate_layout_icons": False, 'container_padding': {'top': 0, 'left': 0, 'bottom': 0, 'right': 0}, 'animation': { 'enabled': True, 'type': 'fadeInOut', 'duration': 200 - "generate_layout_icons": False, }, 'callbacks': { 'on_left': 'next_layout', From 028f44cf2e40db6396ce2ec8eac875ea240e42f7 Mon Sep 17 00:00:00 2001 From: Atif Date: Thu, 12 Jun 2025 09:59:39 +0600 Subject: [PATCH 3/7] increase layout icon stroke width --- src/core/widgets/komorebi/active_layout.py | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/src/core/widgets/komorebi/active_layout.py b/src/core/widgets/komorebi/active_layout.py index 4be3fad3..6629373d 100644 --- a/src/core/widgets/komorebi/active_layout.py +++ b/src/core/widgets/komorebi/active_layout.py @@ -72,7 +72,11 @@ def paintEvent(self, a0): size = self.font().pixelSize() width, height = size, size - stroke_width = 1 + stroke_width = 1.5 + + pen = painter.pen() + pen.setWidthF(stroke_width) + painter.setPen(pen) rect = self.rect() icon_rect = QRectF(0, 0, width, height) @@ -91,7 +95,8 @@ def paintEvent(self, a0): r = (icon_rect.width() / 2) - stroke_width c = icon_rect.center() - icon_rect = icon_rect.adjusted(stroke_width, stroke_width, -stroke_width, -stroke_width) + adjusted_width = stroke_width - 0.5 + icon_rect = icon_rect.adjusted(adjusted_width, adjusted_width, -adjusted_width, -adjusted_width) rounding = icon_rect.width() * 0.1 painter.drawRoundedRect(icon_rect, rounding, rounding) @@ -156,14 +161,11 @@ def line(start, end): rect_right.setWidth(rect_left.width()) rect_right.setHeight(rect_left.height()) - rect_left.moveTopLeft(icon_rect.topLeft() + vec(icon_rect.width() * 0.2, icon_rect.width() * 0.1)) - + rect_left.moveTopLeft( + icon_rect.topLeft() + vec(icon_rect.width() * 0.2, icon_rect.width() * 0.1) + ) rect_right.moveTopLeft( - icon_rect.topLeft() - + vec( - icon_rect.width() * 0.55, - icon_rect.width() * 0.1, - ) + icon_rect.topLeft() + vec(icon_rect.width() * 0.55, icon_rect.width() * 0.1) ) color = self.palette().color(self.foregroundRole()) From e27d6fa3879f9c7fa800f5c87c3e49bc3bc6e0cd Mon Sep 17 00:00:00 2001 From: Atif Date: Fri, 13 Jun 2025 00:25:31 +0600 Subject: [PATCH 4/7] cleanup --- src/core/widgets/komorebi/active_layout.py | 28 ++++++---------------- 1 file changed, 7 insertions(+), 21 deletions(-) diff --git a/src/core/widgets/komorebi/active_layout.py b/src/core/widgets/komorebi/active_layout.py index 6629373d..d1b1d1c9 100644 --- a/src/core/widgets/komorebi/active_layout.py +++ b/src/core/widgets/komorebi/active_layout.py @@ -51,47 +51,33 @@ class LayoutIconWidget(QWidget): def __init__( self, layout_name: str = "bsp", - alignment: Qt.AlignmentFlag = Qt.AlignmentFlag.AlignCenter, ): super().__init__() self.layout_name = layout_name - self._alignment = alignment def sizeHint(self): size = self.font().pixelSize() return QSize(size, size) - def setAlignment(self, alignment: Qt.AlignmentFlag): - self._alignment = alignment - self.updateGeometry() - self.update() + def setAlignment(self, a0): + pass def paintEvent(self, a0): painter = QPainter(self) painter.setRenderHint(QPainter.RenderHint.Antialiasing) + painter.setRenderHint(QPainter.RenderHint.SmoothPixmapTransform) size = self.font().pixelSize() - width, height = size, size - stroke_width = 1.5 + stroke_width = max(1.0, size * 0.08) pen = painter.pen() pen.setWidthF(stroke_width) painter.setPen(pen) rect = self.rect() - icon_rect = QRectF(0, 0, width, height) - - if self._alignment & Qt.AlignmentFlag.AlignHCenter: - icon_rect.moveLeft((rect.width() - width) / 2) - elif self._alignment & Qt.AlignmentFlag.AlignRight: - icon_rect.moveLeft(rect.width() - width) - # else: default is AlignLeft, so no need to move - - if self._alignment & Qt.AlignmentFlag.AlignVCenter: - icon_rect.moveTop((rect.height() - height) / 2) - elif self._alignment & Qt.AlignmentFlag.AlignBottom: - icon_rect.moveTop(rect.height() - height) - # else: default is AlignTop, so no need to move + x = (rect.width() - size) / 2 + y = (rect.height() - size) / 2 + icon_rect = QRectF(x, y, size, size) r = (icon_rect.width() / 2) - stroke_width c = icon_rect.center() From 31960392f2fd3f30f31c943cc882fa374faa1a04 Mon Sep 17 00:00:00 2001 From: Atif Date: Fri, 13 Jun 2025 10:07:51 +0600 Subject: [PATCH 5/7] added separate layout icon for 'Toggle Tiling' mode --- src/core/widgets/komorebi/active_layout.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/core/widgets/komorebi/active_layout.py b/src/core/widgets/komorebi/active_layout.py index d1b1d1c9..7a8982a0 100644 --- a/src/core/widgets/komorebi/active_layout.py +++ b/src/core/widgets/komorebi/active_layout.py @@ -138,6 +138,21 @@ def line(start, end): line(c - vec(-r / 2, r), c + vec(r / 2, r)) elif self.layout_name == "monocle" or self.layout_name == "maximised": pass + elif self.layout_name == "tiling": + rect_left = QRectF(icon_rect) + rect_left.setWidth(icon_rect.width() * 0.5) + rect_left.setHeight(icon_rect.height() * 0.5) + rect_right = QRectF(rect_left) + + rect_left.moveTopLeft( + icon_rect.topLeft() + vec(icon_rect.width() * 0.1, icon_rect.height() * 0.1) + ) + rect_right.moveTopLeft( + icon_rect.topLeft() + vec(icon_rect.width() * 0.35, icon_rect.height() * 0.35) + ) + + painter.fillRect(rect_left, self.palette().color(self.foregroundRole())) + painter.drawRect(rect_right) elif self.layout_name == "paused": rect_left = QRectF(icon_rect) rect_right = QRectF(rect_left) From 11a01caf797b13d5cc37de8e34c34c9dc10194a3 Mon Sep 17 00:00:00 2001 From: Atif Date: Fri, 13 Jun 2025 10:08:45 +0600 Subject: [PATCH 6/7] minor adjustment to bsp and paused layout icons --- src/core/widgets/komorebi/active_layout.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/core/widgets/komorebi/active_layout.py b/src/core/widgets/komorebi/active_layout.py index 7a8982a0..51e74377 100644 --- a/src/core/widgets/komorebi/active_layout.py +++ b/src/core/widgets/komorebi/active_layout.py @@ -107,7 +107,7 @@ def line(start, end): if self.layout_name == "bsp": line(c - vec(0, r), c + vec(0, r)) line(c, c + vec(r, 0)) - line(c + vec(r / 2, 0), c + vec(r / 2, r)) + line(c + vec(r / 2 + 0.25, 0.25), c + vec(r / 2 + 0.25, r)) elif self.layout_name == "columns": line(c - vec(r / 2, r), c + vec(-r / 2, r)) line(c - vec(0, r), c + vec(0, r)) @@ -158,15 +158,15 @@ def line(start, end): rect_right = QRectF(rect_left) rect_left.setWidth(icon_rect.width() * 0.25) - rect_left.setHeight(icon_rect.height() * 0.8) + rect_left.setHeight(icon_rect.height() * 0.7) rect_right.setWidth(rect_left.width()) rect_right.setHeight(rect_left.height()) rect_left.moveTopLeft( - icon_rect.topLeft() + vec(icon_rect.width() * 0.2, icon_rect.width() * 0.1) + icon_rect.topLeft() + vec(icon_rect.width() * 0.2, icon_rect.width() * 0.15) ) rect_right.moveTopLeft( - icon_rect.topLeft() + vec(icon_rect.width() * 0.55, icon_rect.width() * 0.1) + icon_rect.topLeft() + vec(icon_rect.width() * 0.55, icon_rect.width() * 0.15) ) color = self.palette().color(self.foregroundRole()) From 76045ef9f50747556699afad1e803f6f16f24cf1 Mon Sep 17 00:00:00 2001 From: Atif Date: Sat, 14 Jun 2025 14:05:11 +0600 Subject: [PATCH 7/7] some adjustments and and fixed floating icon not showing in the bar --- src/core/widgets/komorebi/active_layout.py | 51 +++++++++++++++------- 1 file changed, 35 insertions(+), 16 deletions(-) diff --git a/src/core/widgets/komorebi/active_layout.py b/src/core/widgets/komorebi/active_layout.py index 51e74377..40964e5c 100644 --- a/src/core/widgets/komorebi/active_layout.py +++ b/src/core/widgets/komorebi/active_layout.py @@ -3,7 +3,14 @@ from PyQt6.QtCore import QPointF, QRectF, QSize, Qt, pyqtSignal from PyQt6.QtGui import QCursor, QPainter -from PyQt6.QtWidgets import QFrame, QHBoxLayout, QLabel, QSizePolicy, QVBoxLayout, QWidget +from PyQt6.QtWidgets import ( + QFrame, + QHBoxLayout, + QLabel, + QSizePolicy, + QVBoxLayout, + QWidget, +) from core.event_enums import KomorebiEvent from core.event_service import EventService @@ -41,6 +48,7 @@ "HorizontalStack": "horizontal_stack", "UltrawideVerticalStack": "ultrawide_vertical_stack", "RightMainVerticalStack": "right_main_vertical_stack", + "Floating": "floating", "Monocle": "monocle", "Maximised": "maximised", "Paused": "paused", @@ -65,8 +73,7 @@ def setAlignment(self, a0): def paintEvent(self, a0): painter = QPainter(self) painter.setRenderHint(QPainter.RenderHint.Antialiasing) - painter.setRenderHint(QPainter.RenderHint.SmoothPixmapTransform) - + size = self.font().pixelSize() stroke_width = max(1.0, size * 0.08) @@ -81,11 +88,13 @@ def paintEvent(self, a0): r = (icon_rect.width() / 2) - stroke_width c = icon_rect.center() - adjusted_width = stroke_width - 0.5 + + adjusted_width = stroke_width * 0.8 icon_rect = icon_rect.adjusted(adjusted_width, adjusted_width, -adjusted_width, -adjusted_width) - rounding = icon_rect.width() * 0.1 - painter.drawRoundedRect(icon_rect, rounding, rounding) - + + corner_radius = icon_rect.width() * 0.1 + painter.drawRoundedRect(icon_rect, corner_radius, corner_radius) + self._draw_icon(painter, icon_rect, r, c) painter.end() @@ -107,7 +116,7 @@ def line(start, end): if self.layout_name == "bsp": line(c - vec(0, r), c + vec(0, r)) line(c, c + vec(r, 0)) - line(c + vec(r / 2 + 0.25, 0.25), c + vec(r / 2 + 0.25, r)) + line(c + vec(r / 2 + 0.2, 0.2), c + vec(r / 2 + 0.2, r)) elif self.layout_name == "columns": line(c - vec(r / 2, r), c + vec(-r / 2, r)) line(c - vec(0, r), c + vec(0, r)) @@ -138,21 +147,28 @@ def line(start, end): line(c - vec(-r / 2, r), c + vec(r / 2, r)) elif self.layout_name == "monocle" or self.layout_name == "maximised": pass - elif self.layout_name == "tiling": + elif self.layout_name == "tiling" or self.layout_name == "floating": rect_left = QRectF(icon_rect) rect_left.setWidth(icon_rect.width() * 0.5) rect_left.setHeight(icon_rect.height() * 0.5) rect_right = QRectF(rect_left) rect_left.moveTopLeft( - icon_rect.topLeft() + vec(icon_rect.width() * 0.1, icon_rect.height() * 0.1) + icon_rect.topLeft() + vec(icon_rect.width() * 0.15, icon_rect.height() * 0.15) ) rect_right.moveTopLeft( - icon_rect.topLeft() + vec(icon_rect.width() * 0.35, icon_rect.height() * 0.35) + icon_rect.topLeft() + vec(icon_rect.width() * 0.3, icon_rect.height() * 0.3) ) - painter.fillRect(rect_left, self.palette().color(self.foregroundRole())) - painter.drawRect(rect_right) + corner_radius = icon_rect.width() * 0.1 + + painter.setBrush(self.palette().brush(self.foregroundRole())) + painter.setPen(Qt.PenStyle.NoPen) + painter.drawRoundedRect(rect_left, corner_radius, corner_radius) + + painter.setBrush(Qt.BrushStyle.NoBrush) + painter.setPen(self.palette().color(self.foregroundRole())) + painter.drawRoundedRect(rect_right, corner_radius, corner_radius) elif self.layout_name == "paused": rect_left = QRectF(icon_rect) rect_right = QRectF(rect_left) @@ -169,9 +185,12 @@ def line(start, end): icon_rect.topLeft() + vec(icon_rect.width() * 0.55, icon_rect.width() * 0.15) ) - color = self.palette().color(self.foregroundRole()) - painter.fillRect(rect_left, color) - painter.fillRect(rect_right, color) + painter.setBrush(self.palette().brush(self.foregroundRole())) + painter.setPen(Qt.PenStyle.NoPen) + + corner_radius = icon_rect.width() * 0.1 + painter.drawRoundedRect(rect_left, corner_radius, corner_radius) + painter.drawRoundedRect(rect_right, corner_radius, corner_radius) else: line(c - vec(0, r), c + vec(0, r)) line(c + vec(0, r / 2), c + vec(r, r / 2))