resolutionrow: make the caller recreate the widget on profile switch

This commit is contained in:
Yaroslav Chvanov
2023-03-03 22:20:47 +03:00
parent c30ad7f11f
commit 122b4e87a0
3 changed files with 30 additions and 35 deletions

View File

@@ -1,6 +1,7 @@
# SPDX-License-Identifier: GPL-2.0-or-later
from .ratbagd import RatbagdResolution
from .util.gobject import disconnect_handlers
import gi
gi.require_version("Gtk", "3.0")
@@ -24,38 +25,24 @@ class ResolutionRow(Gtk.ListBoxRow):
CAP_SEPARATE_XY_RESOLUTION = False
CAP_DISABLE = False
def __init__(self, device, resolution, *args, **kwargs):
def __init__(self, resolution: RatbagdResolution, *args, **kwargs) -> None:
Gtk.ListBoxRow.__init__(self, *args, **kwargs)
self._resolution = None
self._resolution_handler = 0
self._active_handler = 0
self._disabled_handler = 0
self._resolution = resolution
self.resolutions = resolution.resolutions
self._scale_handler = self.scale.connect("value-changed",
self._on_scale_value_changed)
self._disabled_button_handler = self.disable_button.connect("toggled",
self._on_disable_button_toggled)
device.connect("active-profile-changed",
self._on_active_profile_changed, resolution.index)
self._init_values(resolution)
def _init_values(self, resolution):
if self._resolution_handler > 0:
self._resolution.disconnect(self._resolution_handler)
if self._active_handler > 0:
self._resolution.disconnect(self._active_handler)
if self._disabled_handler > 0:
self._resolution.disconnect(self._disabled_handler)
self._resolution = resolution
self.resolutions = resolution.resolutions
self._resolution_handler = resolution.connect("notify::resolution",
self._on_resolution_changed)
self._active_handler = resolution.connect("notify::is-active",
self._on_status_changed)
self._disabled_handler = resolution.connect("notify::is-disabled",
self._on_status_changed)
# https://gitlab.gnome.org/GNOME/pygobject/-/issues/557
self.weak_ref(
lambda: disconnect_handlers(resolution, (self._active_handler, self._disabled_handler))
)
# Get resolution capabilities and update internal values.
if RatbagdResolution.CAP_SEPARATE_XY_RESOLUTION in resolution.capabilities:
@@ -75,10 +62,6 @@ class ResolutionRow(Gtk.ListBoxRow):
self.disable_button.set_active(True)
self._on_status_changed(resolution, pspec=None)
def _on_active_profile_changed(self, device, profile, index):
resolution = profile.resolutions[index]
self._init_values(resolution)
@Gtk.Template.Callback("_on_change_value")
def _on_change_value(self, scale, scroll, value):
# Cursor-controlled slider may get out of the GtkAdjustment's range.
@@ -129,10 +112,6 @@ class ResolutionRow(Gtk.ListBoxRow):
res = int(scale.get_value())
self._on_dpi_values_changed(res=res)
def _on_resolution_changed(self, resolution, pspec):
# RatbagdResolution's resolution has changed, re-initialize.
self._init_values(resolution)
def _on_status_changed(self, resolution, pspec):
# The resolution's status changed, update UI.
self._on_dpi_values_changed()
@@ -174,5 +153,4 @@ class ResolutionRow(Gtk.ListBoxRow):
# Only update new resolution if changed
if (new_res != self._resolution.resolution):
with self._resolution.handler_block(self._resolution_handler):
self._resolution.resolution = new_res
self._resolution.resolution = new_res

View File

@@ -68,10 +68,6 @@ class ResolutionsPage(Gtk.Box):
mousemap.add(label, "#button{}".format(button.index))
mousemap.show_all()
for resolution in profile.resolutions:
row = ResolutionRow(self._device, resolution)
self.listbox.insert(row, resolution.index)
are_report_rates_supported = profile.report_rate != 0 \
and len(profile.report_rates) != 0
self.rate_button_box.set_sensitive(are_report_rates_supported)
@@ -84,6 +80,12 @@ class ResolutionsPage(Gtk.Box):
self._on_active_profile_changed(self._device, profile)
def _on_active_profile_changed(self, device, profile):
# TODO: don't delete the unused "add new resolution" button.
self.listbox.foreach(Gtk.Widget.destroy)
for resolution in profile.resolutions:
row = ResolutionRow(resolution)
self.listbox.insert(row, resolution.index)
# Updates report rate to reflect the new active profile's report rate.
with self.rate_125.handler_block(self._handler_125):
self.rate_125.set_active(profile.report_rate == 125)

15
piper/util/gobject.py Normal file
View File

@@ -0,0 +1,15 @@
from typing import Tuple
from gi.repository import GObject
def disconnect_handlers(obj: GObject.GObject, handlers: Tuple[int, ...]) -> None:
"""Disconnect supplied handlers from the supplied GObject."""
def disconnect_non_zero(handler_id: int) -> None:
if not handler_id > 0:
return
obj.disconnect(handler_id)
for handler in handlers:
disconnect_non_zero(handler)