♻️ refactor(ui): enforce fixed window size and prevent dynamic resizing
This commit is contained in:
3 files changed
+124
-30
No files matched your search
@@ -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
@@ -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;")
|
||||
|
||||
@@ -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):
|
||||
|
||||
Reference in new issue
Block a user