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"?>
<gresources>
<gresource prefix="/com/xronlinux/BreezyDesktop">
<file preprocess="xml-stripblanks">connecteddevice.ui</file>
<file preprocess="xml-stripblanks">nodevice.ui</file>
<file preprocess="xml-stripblanks">window.ui</file>
<file preprocess="xml-stripblanks">gtk/connected-device.ui</file>
<file preprocess="xml-stripblanks">gtk/no-device.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>
</gresource>
</gresources>

View File

@ -1,7 +1,8 @@
from gi.repository import Adw, Gio, Gtk
from .SettingsManager import SettingsManager
from gi.repository import Gio, Gtk
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):
__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('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):
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>
<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="valign">2</property>
<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="titlebar">
<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">
<object class="GtkMenuButton">
<property name="primary">True</property>

View File

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

View File

@ -1,5 +1,5 @@
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):
__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
from gi.repository import GObject
from .XRDriverIPC import XRDriverIPC
from .xrdriveripc import XRDriverIPC
class Logger:
def info(self, message):

View File

@ -18,11 +18,11 @@
# SPDX-License-Identifier: GPL-3.0-or-later
from gi.repository import Gtk
from .StateManager import StateManager
from .statemanager import StateManager
from .connecteddevice import ConnectedDevice
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):
__gtype_name__ = 'BreezydesktopWindow'
@ -45,5 +45,4 @@ class BreezydesktopWindow(Gtk.ApplicationWindow):
self.connected_device.set_device_name(connected_device_name)
else:
self.connected_device.set_visible(False)
self.no_device.set_visible(True)
self.no_device.set_visible(True)