Add shortcut dialog support back in

This commit is contained in:
wheaney 2024-05-06 22:57:35 -07:00
parent d732a1eb07
commit 554e0a607c
13 changed files with 204 additions and 16 deletions

View File

@ -1,9 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<gresources> <gresources>
<gresource prefix="/com/xronlinux/BreezyDesktop"> <gresource prefix="/com/xronlinux/BreezyDesktop">
<file preprocess="xml-stripblanks">connecteddevice.ui</file> <file preprocess="xml-stripblanks">gtk/connected-device.ui</file>
<file preprocess="xml-stripblanks">nodevice.ui</file> <file preprocess="xml-stripblanks">gtk/no-device.ui</file>
<file preprocess="xml-stripblanks">window.ui</file> <file preprocess="xml-stripblanks">gtk/shortcut-dialog.ui</file>
<file preprocess="xml-stripblanks">gtk/window.ui</file>
<file preprocess="xml-stripblanks">gtk/help-overlay.ui</file> <file preprocess="xml-stripblanks">gtk/help-overlay.ui</file>
</gresource> </gresource>
</gresources> </gresources>

View File

@ -1,7 +1,8 @@
from gi.repository import Adw, Gio, Gtk from gi.repository import Gio, Gtk
from .SettingsManager import SettingsManager from .settingsmanager import SettingsManager
from .shortcutdialog import bind_shortcut_settings
@Gtk.Template(resource_path='/com/xronlinux/BreezyDesktop/connecteddevice.ui') @Gtk.Template(resource_path='/com/xronlinux/BreezyDesktop/gtk/connected-device.ui')
class ConnectedDevice(Gtk.Box): class ConnectedDevice(Gtk.Box):
__gtype_name__ = "ConnectedDevice" __gtype_name__ = "ConnectedDevice"
@ -21,5 +22,30 @@ class ConnectedDevice(Gtk.Box):
self.settings.bind('display-distance', self.display_distance_scale, 'value', Gio.SettingsBindFlags.DEFAULT) self.settings.bind('display-distance', self.display_distance_scale, 'value', Gio.SettingsBindFlags.DEFAULT)
self.settings.bind('effect-enable', self.effect_enable_switch, 'active', Gio.SettingsBindFlags.DEFAULT) self.settings.bind('effect-enable', self.effect_enable_switch, 'active', Gio.SettingsBindFlags.DEFAULT)
bind_shortcut_settings(self.get_parent(), [
self.reassign_recenter_display_shortcut_button,
self.reassign_toggle_display_distance_shortcut_button
])
self.bind_set_distance_toggle([
self.set_toggle_display_distance_start_button,
self.set_toggle_display_distance_end_button
])
def set_device_name(self, name): def set_device_name(self, name):
self.device_label.set_markup(f"<b>{name}</b>") self.device_label.set_markup(f"<b>{name}</b>")
def bind_set_distance_toggle(self, widgets):
for widget in widgets:
widget.connect('clicked', lambda *args, widget=widget: on_set_display_distance_toggle(widget))
reload_display_distance_toggle_button(widget)
def reload_display_distance_toggle_button(widget):
distance = SettingsManager.get_instance().settings.get_double(widget.get_name())
if distance: widget.set_label(str(distance))
def on_set_display_distance_toggle(widget):
settings = SettingsManager.get_instance().settings
distance = settings.get_double('display-distance')
settings.set_double(widget.get_name(), distance)
reload_display_distance_toggle_button(widget)

View File

@ -105,7 +105,7 @@
</child> </child>
<child> <child>
<object class="AdwActionRow"> <object class="AdwActionRow">
<property name="title" translatable="true">Distance start and end</property> <property name="title" translatable="true">Display distance start and end</property>
<property name="subtitle" translatable="true">Use the buttons to capture the current display distance as start and end points.</property> <property name="subtitle" translatable="true">Use the buttons to capture the current display distance as start and end points.</property>
<property name="valign">2</property> <property name="valign">2</property>
<child> <child>

View File

@ -0,0 +1,43 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<requires lib="gtk" version="4.0"/>
<template class="ShortcutDialog" parent="GtkDialog">
<property name="modal">1</property>
<property name="default_width">440</property>
<property name="default_height">200</property>
<child internal-child="content_area">
<object class="GtkBox">
<property name="orientation">vertical</property>
<property name="spacing">2</property>
<property name="margin-start">16</property>
<property name="margin-end">16</property>
<property name="margin-top">16</property>
<property name="margin-bottom">16</property>
<child>
<object class="GtkLabel">
<property name="vexpand">1</property>
<property name="label" translatable="yes">Press your keyboard shortcut or 'Backspace' to disable...</property>
</object>
</child>
</object>
</child>
<child type="titlebar">
<object class="GtkHeaderBar">
<property name="title-widget">
<object class="GtkLabel">
<property name="label" translatable="yes">Keyboard Shortcut</property>
<property name="single-line-mode">1</property>
<property name="ellipsize">end</property>
<property name="width-chars">5</property>
<style>
<class name="title"/>
</style>
</object>
</property>
</object>
</child>
<child>
<object class="GtkEventControllerKey" id="event_controller" />
</child>
</template>
</interface>

View File

@ -6,6 +6,17 @@
<property name="default-height">300</property> <property name="default-height">300</property>
<property name="titlebar"> <property name="titlebar">
<object class="GtkHeaderBar" id="header_bar"> <object class="GtkHeaderBar" id="header_bar">
<property name="title-widget">
<object class="GtkLabel">
<property name="label" translatable="yes">Breezy Desktop</property>
<property name="single-line-mode">1</property>
<property name="ellipsize">end</property>
<property name="width-chars">5</property>
<style>
<class name="title"/>
</style>
</object>
</property>
<child type="end"> <child type="end">
<object class="GtkMenuButton"> <object class="GtkMenuButton">
<property name="primary">True</property> <property name="primary">True</property>

View File

@ -31,10 +31,11 @@ breezydesktop_sources = [
'connecteddevice.py', 'connecteddevice.py',
'main.py', 'main.py',
'nodevice.py', 'nodevice.py',
'SettingsManager.py', 'settingsmanager.py',
'StateManager.py', 'shortcutdialog.py',
'statemanager.py',
'window.py', 'window.py',
'XRDriverIPC.py' 'xrdriveripc.py'
] ]
install_data(breezydesktop_sources, install_dir: moduledir) install_data(breezydesktop_sources, install_dir: moduledir)

View File

@ -1,5 +1,5 @@
from gi.repository import Adw, Gtk from gi.repository import Adw, Gtk
@Gtk.Template(resource_path='/com/xronlinux/BreezyDesktop/nodevice.ui') @Gtk.Template(resource_path='/com/xronlinux/BreezyDesktop/gtk/no-device.ui')
class NoDevice(Gtk.Box): class NoDevice(Gtk.Box):
__gtype_name__ = "NoDevice" __gtype_name__ = "NoDevice"

107
ui/src/shortcutdialog.py Normal file
View File

@ -0,0 +1,107 @@
from gi.repository import Gtk, Gdk
from .settingsmanager import SettingsManager
# ported from https://github.com/velitasali/gnome-shell-extension-awesome-tiles
@Gtk.Template(resource_path='/com/xronlinux/BreezyDesktop/gtk/shortcut-dialog.ui')
class ShortcutDialog(Gtk.Dialog):
__gtype_name__ = 'ShortcutDialog'
event_controller = Gtk.Template.Child()
def __init__(self, settings_key):
super(Gtk.Dialog, self).__init__()
self.init_template()
self.settings_key = settings_key
self.key_pressed_connect_id = self.event_controller.connect('key-pressed', self._on_key_pressed)
def _on_key_pressed(self, widget, keyval, keycode, state):
mask = state & Gtk.accelerator_get_default_mod_mask()
mask &= ~Gdk.ModifierType.LOCK_MASK
done = True
if mask == 0 and keyval == Gdk.KEY_Escape:
self.visible = False
elif keyval == Gdk.KEY_BackSpace:
SettingsManager.get_instance().settings.set_strv(self.settings_key, [])
self.close()
elif is_binding_valid(mask, keycode, keyval) and is_accel_valid(state, keyval):
binding = Gtk.accelerator_name_with_keycode(
None,
keyval,
keycode,
state
)
label = Gtk.accelerator_get_label(keyval, state)
# hacky way to store the label, causes warnings from the WM
SettingsManager.get_instance().settings.set_strv(self.settings_key, [binding, label])
self.close()
else:
done = False
if done and self.key_pressed_connect_id:
self.event_controller.disconnect(self.key_pressed_connect_id)
self.key_pressed_connect_id = None
return Gdk.EVENT_STOP
def is_binding_valid(mask, keycode, keyval):
if mask == 0 or mask == Gdk.ModifierType.SHIFT_MASK and keycode != 0:
if keyval >= Gdk.KEY_a and keyval <= Gdk.KEY_z or \
keyval >= Gdk.KEY_A and keyval <= Gdk.KEY_Z or \
keyval >= Gdk.KEY_0 and keyval <= Gdk.KEY_9 or \
keyval >= Gdk.KEY_kana_fullstop and keyval <= Gdk.KEY_semivoicedsound or \
keyval >= Gdk.KEY_Arabic_comma and keyval <= Gdk.KEY_Arabic_sukun or \
keyval >= Gdk.KEY_Serbian_dje and keyval <= Gdk.KEY_Cyrillic_HARDSIGN or \
keyval >= Gdk.KEY_Greek_ALPHAaccent and keyval <= Gdk.KEY_Greek_omega or \
keyval >= Gdk.KEY_hebrew_doublelowline and keyval <= Gdk.KEY_hebrew_taf or \
keyval >= Gdk.KEY_Thai_kokai and keyval <= Gdk.KEY_Thai_lekkao or \
keyval >= Gdk.KEY_Hangul_Kiyeog and keyval <= Gdk.KEY_Hangul_J_YeorinHieuh or \
keyval == Gdk.KEY_space and mask == 0 or \
is_keyval_forbidden(keyval):
return False
return True
def is_keyval_forbidden(keyval):
forbidden_keyvals = [
Gdk.KEY_Home,
Gdk.KEY_Left,
Gdk.KEY_Up,
Gdk.KEY_Right,
Gdk.KEY_Down,
Gdk.KEY_Page_Up,
Gdk.KEY_Page_Down,
Gdk.KEY_End,
Gdk.KEY_Tab,
Gdk.KEY_KP_Enter,
Gdk.KEY_Return,
Gdk.KEY_Mode_switch
]
return keyval in forbidden_keyvals
def is_accel_valid(mask, keyval):
return Gtk.accelerator_valid(keyval, mask) or (keyval == Gdk.KEY_Tab and mask != 0)
def bind_shortcut_settings(window, widgets):
for widget in widgets:
SettingsManager.get_instance().settings.connect('changed::' + widget.get_name(),
lambda *args, widget=widget: reload_shortcut_widget(widget))
widget.connect('clicked', lambda *args, widget=widget: on_assign_shortcut(window, widget))
reload_shortcut_widgets(widgets)
def on_assign_shortcut(window, widget):
dialog = ShortcutDialog(widget.get_name())
dialog.set_transient_for(widget.get_ancestor(Gtk.Window))
dialog.present()
def reload_shortcut_widget(widget):
shortcut = SettingsManager.get_instance().settings.get_strv(widget.get_name())
widget.set_label(shortcut[1] if len(shortcut) > 1 else 'Disabled')
def reload_shortcut_widgets(widgets):
for widget in widgets:
reload_shortcut_widget(widget)

View File

@ -1,6 +1,6 @@
import threading import threading
from gi.repository import GObject from gi.repository import GObject
from .XRDriverIPC import XRDriverIPC from .xrdriveripc import XRDriverIPC
class Logger: class Logger:
def info(self, message): def info(self, message):

View File

@ -18,11 +18,11 @@
# SPDX-License-Identifier: GPL-3.0-or-later # SPDX-License-Identifier: GPL-3.0-or-later
from gi.repository import Gtk from gi.repository import Gtk
from .StateManager import StateManager from .statemanager import StateManager
from .connecteddevice import ConnectedDevice from .connecteddevice import ConnectedDevice
from .nodevice import NoDevice from .nodevice import NoDevice
@Gtk.Template(resource_path='/com/xronlinux/BreezyDesktop/window.ui') @Gtk.Template(resource_path='/com/xronlinux/BreezyDesktop/gtk/window.ui')
class BreezydesktopWindow(Gtk.ApplicationWindow): class BreezydesktopWindow(Gtk.ApplicationWindow):
__gtype_name__ = 'BreezydesktopWindow' __gtype_name__ = 'BreezydesktopWindow'
@ -45,5 +45,4 @@ class BreezydesktopWindow(Gtk.ApplicationWindow):
self.connected_device.set_device_name(connected_device_name) self.connected_device.set_device_name(connected_device_name)
else: else:
self.connected_device.set_visible(False) self.connected_device.set_visible(False)
self.no_device.set_visible(True) self.no_device.set_visible(True)