♻️ refactor(ui): enforce fixed window size and prevent dynamic resizing

This commit is contained in:
sankalp committed 2025-07-21 07:55:19 +05:45
1 parent 3d8f059957
commit d5d2721820
3 files changed
+124 -30

No files matched your search

+27 -9
View File
@@ -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()
+79 -13
View File
@@ -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;")
+18 -8
View File
@@ -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):