From d5d2721820543c034edbf07afc734084dac80f7e Mon Sep 17 00:00:00 2001 From: S4NKALP Date: Mon, 21 Jul 2025 07:55:19 +0545 Subject: [PATCH] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20refactor(ui):=20enforce=20?= =?UTF-8?q?fixed=20window=20size=20and=20prevent=20dynamic=20resizing?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config/settings/bluetooth_tab.py | 36 +++++++++---- config/settings/gui.py | 92 +++++++++++++++++++++++++++----- config/settings/wifi_tab.py | 26 ++++++--- 3 files changed, 124 insertions(+), 30 deletions(-) diff --git a/config/settings/bluetooth_tab.py b/config/settings/bluetooth_tab.py index 7ed0aa9..a891ac2 100644 --- a/config/settings/bluetooth_tab.py +++ b/config/settings/bluetooth_tab.py @@ -208,12 +208,17 @@ class BluetoothTab: def __init__(self): self.bluetooth_client = BluetoothClient(on_device_added=self.on_device_added) self.device_widgets = {} + self.window_size_enforcer = None # Connect to bluetooth client signals self.bluetooth_client.connect("notify::enabled", self._on_bluetooth_changed) self.bluetooth_client.connect("notify::scanning", self._update_scan_button) self.bluetooth_client.connect("device-removed", self.on_device_removed) + def set_window_size_enforcer(self, enforcer_func): + """Set the window size enforcer function from the main GUI""" + self.window_size_enforcer = enforcer_func + def create_bluetooth_tab(self): @@ -224,8 +229,8 @@ class BluetoothTab: style="padding: 0; margin: 15px;" ) - # Set fixed size for the main container to match GUI window - main_vbox.set_size_request(620, 580) + # Set fixed size for the main container to match tab stack dimensions + main_vbox.set_size_request(580, 580) # Create widgets first self.bluetooth_subtitle = Label( @@ -277,9 +282,11 @@ class BluetoothTab: main_vbox.add(header_box) - # Device containers + # Device containers with size constraints self.paired_box = Box(spacing=20, orientation="v") - self.available_box = Box(spacing=20, orientation="v", ) + self.paired_box.set_size_request(560, -1) + self.available_box = Box(spacing=20, orientation="v") + self.available_box.set_size_request(560, -1) content_box = Box( spacing=8, @@ -291,20 +298,23 @@ class BluetoothTab: self.available_box, ] ) + # Set size constraints for content box + content_box.set_size_request(560, -1) # Devices list in scrolled window devices_scrolled = ScrolledWindow( name="bluetooth-devices", h_scrollbar_policy="never", v_scrollbar_policy="automatic", - h_expand=True, - v_expand=True, + h_expand=False, + v_expand=False, propagate_width=False, propagate_height=False, child=content_box, ) - devices_scrolled.set_size_request(-1, 500) + # Set fixed size to prevent dynamic resizing + devices_scrolled.set_size_request(580, 500) main_vbox.add(devices_scrolled) # Initialize bluetooth status and populate existing devices @@ -374,9 +384,13 @@ class BluetoothTab: self.device_widgets[address] = slot if device.paired or device.trusted: - return self.paired_box.add(slot) + self.paired_box.add(slot) else: - return self.available_box.add(slot) + self.available_box.add(slot) + + # Enforce window size after adding device + if self.window_size_enforcer: + GLib.idle_add(self.window_size_enforcer) def on_device_removed(self, client: BluetoothClient, address: str): """Handle device removed""" @@ -389,6 +403,10 @@ class BluetoothTab: # Remove from tracking del self.device_widgets[address] + # Enforce window size after removing device + if self.window_size_enforcer: + GLib.idle_add(self.window_size_enforcer) + def _on_bluetooth_switch_toggled(self, switch, gparam): """Handle Bluetooth switch toggle""" is_active = switch.get_active() diff --git a/config/settings/gui.py b/config/settings/gui.py index db31ccd..f3ebb19 100644 --- a/config/settings/gui.py +++ b/config/settings/gui.py @@ -13,7 +13,7 @@ from fabric.widgets.label import Label from fabric.widgets.scrolledwindow import ScrolledWindow from fabric.widgets.stack import Stack from fabric.widgets.window import Window -from gi.repository import GdkPixbuf, GLib, Gtk +from gi.repository import Gdk, GdkPixbuf, GLib, Gtk from PIL import Image from config.data import APP_NAME, APP_NAME_CAP, NOTIF_POS_DEFAULT, NOTIF_POS_KEY @@ -34,6 +34,18 @@ class HyprConfGUI(Window): ) self.set_resizable(False) + # Set strict size constraints to prevent dynamic resizing + self.set_size_request(640, 640) + self.set_default_size(640, 640) + # Set geometry hints to enforce fixed size + geometry = Gdk.Geometry() + geometry.min_width = 640 + geometry.max_width = 640 + geometry.min_height = 640 + geometry.max_height = 640 + self.set_geometry_hints(None, geometry, + Gdk.WindowHints.MIN_SIZE | Gdk.WindowHints.MAX_SIZE) + self.themes = ["Pills", "Dense", "Edge"] self.selected_face_icon = None self.show_lock_checkbox = show_lock_checkbox @@ -43,10 +55,18 @@ class HyprConfGUI(Window): self.wifi_tab = WiFiTab() self.bluetooth_tab = BluetoothTab() + # Pass window size enforcement method to tabs + self.wifi_tab.set_window_size_enforcer(self.enforce_window_size) + self.bluetooth_tab.set_window_size_enforcer(self.enforce_window_size) + root_box = Box(orientation="v", spacing=10, style="margin: 10px;") + # Set fixed size for root container + root_box.set_size_request(620, 620) self.add(root_box) main_content_box = Box(orientation="h", spacing=6, v_expand=False, h_expand=False) + # Set fixed size for main content to prevent expansion + main_content_box.set_size_request(620, 580) root_box.add(main_content_box) self.tab_stack = Stack( @@ -55,6 +75,9 @@ class HyprConfGUI(Window): v_expand=False, h_expand=False, ) + # Set fixed size for tab stack + self.tab_stack.set_size_request(580, 580) + self.wifi_tab_content = self.wifi_tab.create_wifi_tab() self.bluetooth_tab_content = self.bluetooth_tab.create_bluetooth_tab() self.key_bindings_tab_content = self.create_key_bindings_tab() @@ -80,10 +103,14 @@ class HyprConfGUI(Window): tab_switcher = Gtk.StackSwitcher() tab_switcher.set_stack(self.tab_stack) tab_switcher.set_orientation(Gtk.Orientation.VERTICAL) + # Set fixed width for tab switcher + tab_switcher.set_size_request(40, -1) main_content_box.add(tab_switcher) main_content_box.add(self.tab_stack) button_box = Box(orientation="h", spacing=10, h_align="end") + # Set fixed height for button box + button_box.set_size_request(-1, 40) reset_btn = Button(label="Reset to Defaults", on_clicked=self.on_reset) button_box.add(reset_btn) close_btn = Button(label="Close", on_clicked=self.on_close) @@ -92,24 +119,35 @@ class HyprConfGUI(Window): button_box.add(accept_btn) root_box.add(button_box) - # Force window size after all content is added + # Force window size after all content is added and on any size changes self.connect("realize", self._force_window_size) + self.connect("size-allocate", self._on_size_allocate) def _force_window_size(self, widget): """Force the window to respect the declared size""" self.resize(640, 640) self.set_size_request(640, 640) + def _on_size_allocate(self, widget, allocation): + """Prevent window from changing size during allocation""" + if allocation.width != 640 or allocation.height != 640: + GLib.idle_add(lambda: self.resize(640, 640)) + + def enforce_window_size(self): + """Public method to enforce window size - can be called by tabs""" + self._force_window_size(self) + def create_key_bindings_tab(self): scrolled_window = ScrolledWindow( h_scrollbar_policy="never", v_scrollbar_policy="automatic", h_expand=False, v_expand=False, - propagate_width=True, - propagate_height=True, + propagate_width=False, + propagate_height=False, ) - scrolled_window.set_size_request(620, 580) # Set explicit size for content area + # Set fixed size to match tab stack dimensions + scrolled_window.set_size_request(580, 580) main_vbox = Box(orientation="v", spacing=10, style="margin: 15px;") scrolled_window.add(main_vbox) @@ -185,11 +223,13 @@ class HyprConfGUI(Window): scrolled_window = ScrolledWindow( h_scrollbar_policy="never", v_scrollbar_policy="automatic", - h_expand=True, - v_expand=True, + h_expand=False, + v_expand=False, propagate_width=False, propagate_height=False, ) + # Set fixed size to match tab stack dimensions + scrolled_window.set_size_request(580, 580) vbox = Box(orientation="v", spacing=15, style="margin: 15px;") scrolled_window.add(vbox) @@ -620,11 +660,13 @@ class HyprConfGUI(Window): scrolled_window = ScrolledWindow( h_scrollbar_policy="never", v_scrollbar_policy="automatic", - h_expand=True, - v_expand=True, + h_expand=False, + v_expand=False, propagate_width=False, propagate_height=False, ) + # Set fixed size to match tab stack dimensions + scrolled_window.set_size_request(580, 580) vbox = Box(orientation="v", spacing=15, style="margin: 15px;") scrolled_window.add(vbox) @@ -796,7 +838,23 @@ class HyprConfGUI(Window): label="Disk directories for Metrics", h_align="start", v_align="center" ) vbox.add(disks_label) + + # Create a scrolled container for disk entries to prevent overflow + disk_entries_scrolled = ScrolledWindow( + h_scrollbar_policy="never", + v_scrollbar_policy="automatic", + h_expand=False, + v_expand=False, + propagate_width=False, + propagate_height=False, + ) + # Set fixed size for disk entries container + disk_entries_scrolled.set_size_request(550, 120) + self.disk_entries = Box(orientation="v", spacing=8, h_align="start") + # Set size constraints for the disk entries box + self.disk_entries.set_size_request(530, -1) + disk_entries_scrolled.add(self.disk_entries) self._create_disk_edit_entry_func = lambda path: self._add_disk_entry_widget( path @@ -804,7 +862,7 @@ class HyprConfGUI(Window): for p in bind_vars.get("metrics_disks", ["/"]): self._create_disk_edit_entry_func(p) - vbox.add(self.disk_entries) + vbox.add(disk_entries_scrolled) add_container = Gtk.Box( orientation=Gtk.Orientation.HORIZONTAL, @@ -823,18 +881,26 @@ class HyprConfGUI(Window): def _add_disk_entry_widget(self, path): """Helper to add a disk entry row to the disk_entries Box.""" bar = Box(orientation="h", spacing=10, h_align="start") + # Set fixed height for disk entry rows + bar.set_size_request(-1, 30) entry = Entry(text=path, h_expand=True) bar.add(entry) x_btn = Button(label="X") x_btn.connect( "clicked", - lambda _, current_bar_to_remove=bar: self.disk_entries.remove( - current_bar_to_remove - ), + lambda _, current_bar_to_remove=bar: self._remove_disk_entry(current_bar_to_remove), ) bar.add(x_btn) self.disk_entries.add(bar) self.disk_entries.show_all() + # Enforce window size after adding content + GLib.idle_add(self.enforce_window_size) + + def _remove_disk_entry(self, bar_to_remove): + """Helper to remove a disk entry and enforce window size""" + self.disk_entries.remove(bar_to_remove) + # Enforce window size after removing content + GLib.idle_add(self.enforce_window_size) def create_about_tab(self): vbox = Box(orientation="v", spacing=18, style="margin: 30px;") diff --git a/config/settings/wifi_tab.py b/config/settings/wifi_tab.py index 3e7361d..1422d5a 100644 --- a/config/settings/wifi_tab.py +++ b/config/settings/wifi_tab.py @@ -21,14 +21,19 @@ class WiFiTab: self.access_point_widgets = {} self.password_entries = {} self.connecting_to = None - + self.window_size_enforcer = None + # Connect to network client signals self.network_client.connect("ready", self._on_network_ready) self.network_client.connect("changed", self._on_network_changed) - + if self.network_client.is_ready: self._setup_network_signals() + def set_window_size_enforcer(self, enforcer_func): + """Set the window size enforcer function from the main GUI""" + self.window_size_enforcer = enforcer_func + def _on_network_ready(self, *args): """Called when network client is ready""" self._setup_network_signals() @@ -65,8 +70,8 @@ class WiFiTab: style="padding: 0; margin: 15px;" ) - # Set fixed size for the main container to match GUI window - main_vbox.set_size_request(620, 580) # Match GUI window content area + # Set fixed size for the main container to match tab stack dimensions + main_vbox.set_size_request(580, 580) # Header section with title and controls header_box = Box( @@ -124,19 +129,21 @@ class WiFiTab: self.networks_scrolled = ScrolledWindow( h_scrollbar_policy="never", v_scrollbar_policy="automatic", - h_expand=True, - v_expand=True, + h_expand=False, + v_expand=False, propagate_width=False, propagate_height=False, ) - # Set size to match available space (580 - header space ≈ 500) - self.networks_scrolled.set_size_request(-1, 500) + # Set fixed size to prevent dynamic resizing (580 - header space ≈ 500) + self.networks_scrolled.set_size_request(580, 500) self.networks_container = Box( orientation="v", spacing=0, ) + # Set size constraints for networks container + self.networks_container.set_size_request(560, -1) self.networks_scrolled.add(self.networks_container) main_vbox.add(self.networks_scrolled) @@ -162,6 +169,9 @@ class WiFiTab: self._populate_networks() self.networks_container.show_all() + # Enforce window size after content changes + if self.window_size_enforcer: + GLib.idle_add(self.window_size_enforcer) return False def _update_wifi_status(self):