🐛 fix(ui): prevent window resizing in settings app

This commit is contained in:
sankalp committed 2025-07-21 09:16:20 +05:45
1 parent 36904e84e8
commit bb64eb17d7
6 files changed
+279 -258

No files matched your search

+80 -66
View File
@@ -1,3 +1,5 @@
import subprocess
from fabric.bluetooth import BluetoothClient, BluetoothDevice
from fabric.widgets.box import Box
from fabric.widgets.button import Button
@@ -6,7 +8,6 @@ from fabric.widgets.image import Image
from fabric.widgets.label import Label
from fabric.widgets.scrolledwindow import ScrolledWindow
from gi.repository import GLib, Gtk
import subprocess
import utils.icons as icons
@@ -20,18 +21,20 @@ class BluetoothDeviceSlot(CenterBox):
"notify::closed", lambda *_: self.device.closed and self.destroy()
)
self.connection_label = Label(markup=icons.bluetooth_disconnected, style="font-size: 22px;")
self.connection_label = Label(
markup=icons.bluetooth_disconnected, style="font-size: 22px;"
)
self.connect_button = Button(
label="Connect",
on_clicked=lambda *_: self._handle_device_action(),
)
# Create device name label that we can update
self.device_name_label = Label(
label=device.alias or device.name,
h_expand=True,
h_align="start",
ellipsization="end"
ellipsization="end",
)
self.start_children = [
@@ -50,8 +53,6 @@ class BluetoothDeviceSlot(CenterBox):
self.device.emit("changed")
def _handle_device_action(self):
"""Handle connect/disconnect button click"""
if self.device.connected:
@@ -71,23 +72,31 @@ class BluetoothDeviceSlot(CenterBox):
device_address = self.device.address
# Show pairing notification
subprocess.run([
"notify-send",
"Bluetooth Pairing",
f"Attempting to pair with {device_name}...",
"--icon=bluetooth",
"--urgency=normal",
"--app-name=Bluetooth"
], check=False)
subprocess.run(
[
"notify-send",
"Bluetooth Pairing",
f"Attempting to pair with {device_name}...",
"--icon=bluetooth",
"--urgency=normal",
"--app-name=Bluetooth",
],
check=False,
)
# Use bluetoothctl to pair the device
# This will trigger the system's pairing agent which should show the pairing dialog
pairing_process = subprocess.Popen([
"bluetoothctl", "pair", device_address
], stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
pairing_process = subprocess.Popen(
["bluetoothctl", "pair", device_address],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
text=True,
)
# Monitor the pairing process in a separate thread
GLib.timeout_add(100, self._monitor_pairing_process, pairing_process, device_name)
GLib.timeout_add(
100, self._monitor_pairing_process, pairing_process, device_name
)
except Exception as e:
print(f"Failed to start pairing process: {e}")
@@ -121,7 +130,7 @@ class BluetoothDeviceSlot(CenterBox):
subprocess.run(["bluetoothctl", "trust", device_address], check=False)
# Connect to the device
GLib.timeout_add(1000, lambda: setattr(self.device, 'connected', True))
GLib.timeout_add(1000, lambda: setattr(self.device, "connected", True))
except Exception as e:
print(f"Failed to trust/connect device: {e}")
@@ -130,14 +139,17 @@ class BluetoothDeviceSlot(CenterBox):
"""Show notification when pairing succeeds"""
try:
device_name = self.device.alias or self.device.name
subprocess.run([
"notify-send",
"Bluetooth Paired",
f"Successfully paired with {device_name}",
"--icon=bluetooth",
"--urgency=normal",
"--app-name=Bluetooth"
], check=False)
subprocess.run(
[
"notify-send",
"Bluetooth Paired",
f"Successfully paired with {device_name}",
"--icon=bluetooth",
"--urgency=normal",
"--app-name=Bluetooth",
],
check=False,
)
except Exception as e:
print(f"Failed to send pairing success notification: {e}")
@@ -145,28 +157,33 @@ class BluetoothDeviceSlot(CenterBox):
"""Show notification when pairing fails"""
try:
device_name = self.device.alias or self.device.name
subprocess.run([
"notify-send",
"Bluetooth Pairing Failed",
f"Failed to pair with {device_name}",
"--icon=bluetooth-disabled",
"--urgency=normal",
"--app-name=Bluetooth"
], check=False)
subprocess.run(
[
"notify-send",
"Bluetooth Pairing Failed",
f"Failed to pair with {device_name}",
"--icon=bluetooth-disabled",
"--urgency=normal",
"--app-name=Bluetooth",
],
check=False,
)
except Exception as e:
print(f"Failed to send pairing failed notification: {e}")
def on_changed(self, *_):
# Update connection icon
self.connection_label.set_markup(
icons.bluetooth_connected if self.device.connected else icons.bluetooth_disconnected
icons.bluetooth_connected
if self.device.connected
else icons.bluetooth_disconnected
)
# Check for pairing state changes and show notifications
base_name = self.device.alias or self.device.name
# Track pairing success/failure
if hasattr(self, '_was_pairing') and self._was_pairing:
if hasattr(self, "_was_pairing") and self._was_pairing:
if self.device.paired and not self.device.connecting:
# Pairing succeeded
self._show_pairing_success_notification()
@@ -201,7 +218,6 @@ class BluetoothDeviceSlot(CenterBox):
self.device_name_label.set_label(status_text)
class BluetoothTab:
"""Bluetooth device management tab for settings"""
@@ -219,32 +235,27 @@ class BluetoothTab:
"""Set the window size enforcer function from the main GUI"""
self.window_size_enforcer = enforcer_func
def create_bluetooth_tab(self):
"""Create the Bluetooth tab content"""
main_vbox = Box(
orientation="v",
spacing=0,
style="padding: 0; margin: 15px;"
)
main_vbox = Box(orientation="v", spacing=0, style="padding: 0; margin: 15px;")
# 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(
markup="<span>Find and connect to Bluetooth devices</span>",
h_align="start"
markup="<span>Find and connect to Bluetooth devices</span>", h_align="start"
)
self.bluetooth_switch = Gtk.Switch()
self.scan_icon = Label(name="bluetooth-tab-icon", markup=icons.radar, style="font-size: 18px;")
self.scan_icon = Label(
name="bluetooth-tab-icon", markup=icons.radar, style="font-size: 18px;"
)
self.scan_button = Button(
name="bluetooth-scan",
child=self.scan_icon,
tooltip_text="Scan for devices",
on_clicked=lambda *_: self.bluetooth_client.toggle_scan(),
style="margin:10px;"
style="margin:10px;",
)
# Header section with title and controls
@@ -258,10 +269,10 @@ class BluetoothTab:
children=[
Label(
markup="<span size='large'><b>Bluetooth</b></span>",
h_align="start"
h_align="start",
),
self.bluetooth_subtitle,
]
],
)
],
end_children=[
@@ -271,14 +282,16 @@ class BluetoothTab:
children=[
self.bluetooth_switch,
self.scan_button,
]
],
)
]
],
)
# Set up switch
self.bluetooth_switch.set_valign(Gtk.Align.CENTER)
self.bluetooth_switch.connect("notify::active", self._on_bluetooth_switch_toggled)
self.bluetooth_switch.connect(
"notify::active", self._on_bluetooth_switch_toggled
)
main_vbox.add(header_box)
@@ -292,11 +305,19 @@ class BluetoothTab:
spacing=8,
orientation="v",
children=[
Label(name="bluetooth-section", markup="<b>Paired Devices</b>", h_align="start"),
Label(
name="bluetooth-section",
markup="<b>Paired Devices</b>",
h_align="start",
),
self.paired_box,
Label(name="bluetooth-section", markup="<b>Available Devices</b>", h_align="start"),
Label(
name="bluetooth-section",
markup="<b>Available Devices</b>",
h_align="start",
),
self.available_box,
]
],
)
# Set size constraints for content box
content_box.set_size_request(560, -1)
@@ -335,9 +356,7 @@ class BluetoothTab:
self.scan_button.set_sensitive(True)
else:
self.bluetooth_switch.set_active(False)
self.bluetooth_subtitle.set_markup(
"<span>Bluetooth is turned off</span>"
)
self.bluetooth_subtitle.set_markup("<span>Bluetooth is turned off</span>")
self.scan_button.set_sensitive(False)
def _on_bluetooth_changed(self, *args):
@@ -362,9 +381,8 @@ class BluetoothTab:
"""Populate existing devices when tab is created"""
if not self.bluetooth_client or not self.bluetooth_client.enabled:
return
devices = self.bluetooth_client.devices
for device in devices:
self.on_device_added(self.bluetooth_client, device.address)
@@ -430,7 +448,3 @@ class BluetoothTab:
"""Clear and repopulate all devices"""
self._clear_all_devices()
self._populate_existing_devices()