From cc81f863c5014ddf2a3ec8b2f2a3096a618d72a9 Mon Sep 17 00:00:00 2001
From: wheaney <42350981+wheaney@users.noreply.github.com>
Date: Sat, 22 Feb 2025 18:13:21 -0800
Subject: [PATCH] Drop display distance easing while moving the slider, update
the UI (WIP), add a "zoom on focus" toggle
---
gnome/src/virtualmonitorsactor.js | 28 +++++-
ui/src/connecteddevice.py | 90 +++++++++++++++----
ui/src/gtk/connected-device.ui | 140 +++++++++++++++++++++---------
ui/src/gtk/no-device.ui | 12 ---
ui/src/nodevice.py | 8 +-
ui/src/window.py | 8 +-
6 files changed, 207 insertions(+), 79 deletions(-)
diff --git a/gnome/src/virtualmonitorsactor.js b/gnome/src/virtualmonitorsactor.js
index 834185a..d7b3327 100644
--- a/gnome/src/virtualmonitorsactor.js
+++ b/gnome/src/virtualmonitorsactor.js
@@ -366,6 +366,13 @@ export const VirtualMonitorEffect = GObject.registerClass({
GObject.ParamFlags.READWRITE,
-1, 100, -1
),
+ 'display-zoom-on-focus': GObject.ParamSpec.boolean(
+ 'display-zoom-on-focus',
+ 'Display zoom on focus',
+ 'Automatically move a display closer when it becomes focused.',
+ GObject.ParamFlags.READWRITE,
+ true
+ ),
'display-distance': GObject.ParamSpec.double(
'display-distance',
'Display Distance',
@@ -444,6 +451,7 @@ export const VirtualMonitorEffect = GObject.registerClass({
super(params);
this._current_display_distance = this._is_focused() ? this.display_distance : this.display_distance_default;
+ this.no_distance_ease = false;
this.connect('notify::display-distance', this._update_display_distance.bind(this));
this.connect('notify::focused-monitor-index', this._update_display_distance.bind(this));
@@ -464,6 +472,13 @@ export const VirtualMonitorEffect = GObject.registerClass({
this._distance_ease_timeline.stop();
}
+
+ if (this.no_distance_ease) {
+ this._current_display_distance = desired_distance;
+ this._update_display_position_uniforms();
+ this.no_distance_ease = false;
+ return;
+ }
// if we're the focused display, we'll double the timeline and wait for the first half to let other
// displays ease out first
@@ -792,6 +807,13 @@ export const VirtualMonitorsActor = GObject.registerClass({
2.5,
1.0
),
+ 'display-zoom-on-focus': GObject.ParamSpec.boolean(
+ 'display-zoom-on-focus',
+ 'Display zoom on focus',
+ 'Automatically move a display closer when it becomes focused.',
+ GObject.ParamFlags.READWRITE,
+ true
+ ),
'display-distance': GObject.ParamSpec.double(
'display-distance',
'Display Distance',
@@ -976,7 +998,6 @@ export const VirtualMonitorsActor = GObject.registerClass({
'monitor-placements',
'imu-snapshots',
'focused-monitor-index',
- 'display-distance',
'lens-vector',
'look-ahead-override',
'disable-anti-aliasing',
@@ -986,8 +1007,11 @@ export const VirtualMonitorsActor = GObject.registerClass({
}));
const updateEffectDistanceDefault = (() => {
+ effect.no_distance_ease = Math.abs(this.display_distance - effect.display_distance) <= 0.05;
+ effect.display_distance = this.display_distance;
effect.display_distance_default = this._display_distance_default();
}).bind(this);
+ this._property_connections.push(this.connect('notify::display-distance', updateEffectDistanceDefault));
this._property_connections.push(this.connect('notify::toggle-display-distance-start', updateEffectDistanceDefault));
this._property_connections.push(this.connect('notify::toggle-display-distance-end', updateEffectDistanceDefault));
@@ -1047,7 +1071,7 @@ export const VirtualMonitorsActor = GObject.registerClass({
}
_display_distance_default() {
- return Math.max(this.toggle_display_distance_start, this.toggle_display_distance_end);
+ return Math.max(this.display_distance, this.toggle_display_distance_start, this.toggle_display_distance_end);
}
_fov_details() {
diff --git a/ui/src/connecteddevice.py b/ui/src/connecteddevice.py
index f262a7e..7cd9a7e 100644
--- a/ui/src/connecteddevice.py
+++ b/ui/src/connecteddevice.py
@@ -23,6 +23,7 @@ class ConnectedDevice(Gtk.Box):
device_label = Gtk.Template.Child()
effect_enable_switch = Gtk.Template.Child()
+ display_zoom_on_focus_switch = Gtk.Template.Child()
display_distance_scale = Gtk.Template.Child()
display_distance_adjustment = Gtk.Template.Child()
# display_size_scale = Gtk.Template.Child()
@@ -37,8 +38,11 @@ class ConnectedDevice(Gtk.Box):
add_virtual_display_menu = Gtk.Template.Child()
add_virtual_display_button = Gtk.Template.Child()
launch_display_settings_button = Gtk.Template.Child()
- set_toggle_display_distance_start_button = Gtk.Template.Child()
- set_toggle_display_distance_end_button = Gtk.Template.Child()
+ all_displays_distance_label = Gtk.Template.Child()
+ set_all_displays_distance_button = Gtk.Template.Child()
+ focused_display_distance_label = Gtk.Template.Child()
+ set_focused_display_distance_button = Gtk.Template.Child()
+ display_distance_presets_description = Gtk.Template.Child()
reassign_toggle_xr_effect_shortcut_button = Gtk.Template.Child()
toggle_xr_effect_shortcut_label = Gtk.Template.Child()
reassign_recenter_display_shortcut_button = Gtk.Template.Child()
@@ -68,6 +72,7 @@ class ConnectedDevice(Gtk.Box):
self.init_template()
self.active = True
self.all_enabled_state_inputs = [
+ self.display_zoom_on_focus_switch,
self.display_distance_scale,
# self.display_size_scale,
# self.follow_mode_switch,
@@ -75,8 +80,8 @@ class ConnectedDevice(Gtk.Box):
# self.curved_display_switch,
self.add_virtual_display_menu,
self.add_virtual_display_button,
- self.set_toggle_display_distance_start_button,
- self.set_toggle_display_distance_end_button,
+ self.set_all_displays_distance_button,
+ self.set_focused_display_distance_button,
self.movement_look_ahead_scale,
self.monitor_wrapping_scheme_menu,
self.monitor_spacing_scale,
@@ -105,6 +110,7 @@ class ConnectedDevice(Gtk.Box):
self.settings.bind('viewport-offset-y', self.viewport_offset_y_adjustment, 'value', Gio.SettingsBindFlags.DEFAULT)
self.settings.connect('changed::monitor-wrapping-scheme', self._handle_monitor_wrapping_scheme_setting_changed)
self.desktop_settings.bind('text-scaling-factor', self.text_scaling_adjustment, 'value', Gio.SettingsBindFlags.DEFAULT)
+ self.display_zoom_on_focus_switch.connect('notify::active', self._handle_zoom_on_focus_switch_changed)
self.monitor_wrapping_scheme_menu.connect('changed', self._handle_monitor_wrapping_scheme_menu_changed)
self._handle_monitor_wrapping_scheme_setting_changed(self.settings, self.settings.get_string('monitor-wrapping-scheme'))
@@ -115,12 +121,15 @@ class ConnectedDevice(Gtk.Box):
[self.reassign_toggle_follow_shortcut_button, self.toggle_follow_shortcut_label]
])
- self.bind_set_distance_toggle([
- self.set_toggle_display_distance_start_button,
- self.set_toggle_display_distance_end_button
- ])
+ self.set_all_displays_distance_button.connect('clicked', self._on_set_all_displays_distance)
+ self.set_focused_display_distance_button.connect('clicked', self.on_set_focused_display_distance)
+ self._set_all_displays_distance(self.settings.get_double('toggle-display-distance-end'))
+ self._set_focused_display_distance(self.settings.get_double('toggle-display-distance-start'))
+ self.display_distance_adjustment.connect('value-changed', self._on_display_distance_update)
+ self._on_display_distance_update(self.display_distance_adjustment)
+
self.add_virtual_display_menu.set_active_id('1080p')
- self.add_virtual_display_button.connect('clicked', self.on_add_virtual_display)
+ self.add_virtual_display_button.connect('clicked', self._on_add_virtual_display)
self.launch_display_settings_button.connect('clicked', self._launch_display_settings)
self.state_manager = StateManager.get_instance()
@@ -147,6 +156,9 @@ class ConnectedDevice(Gtk.Box):
self.virtual_display_manager.connect('notify::displays', self._on_virtual_displays_update)
self._on_virtual_displays_update(self.virtual_display_manager, None)
+ self.display_distance_presets_description.set_markup(
+ _("These presets are used unless manually overridden by the slider above."))
+
self.connect("destroy", self._on_widget_destroy)
self.virtual_displays_by_pid = {}
@@ -157,6 +169,16 @@ class ConnectedDevice(Gtk.Box):
if appinfo.get_id() == 'gnome-display-panel.desktop':
self._settings_displays_app_info = appinfo
break
+
+ def _handle_zoom_on_focus_switch_changed(self, widget, param):
+ display_distance = self.settings.get_double('display-distance')
+ toggle_display_distance_end = self.settings.get_double('toggle-display-distance-end')
+ toggle_display_distance_start = self.settings.get_double('toggle-display-distance-start')
+ is_zoom_on_focus_already_enabled = display_distance < toggle_display_distance_end
+ if widget.get_active() and not is_zoom_on_focus_already_enabled:
+ self.settings.set_double('display-distance', toggle_display_distance_start)
+ elif not widget.get_active() and is_zoom_on_focus_already_enabled:
+ self.settings.set_double('display-distance', toggle_display_distance_end)
def _handle_monitor_wrapping_scheme_setting_changed(self, settings, val):
self.monitor_wrapping_scheme_menu.set_active_id(val)
@@ -219,13 +241,51 @@ class ConnectedDevice(Gtk.Box):
def set_device_name(self, name):
self.device_label.set_markup(f"{name}")
-
- 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 on_add_virtual_display(self, *args):
+ def _on_display_distance_update(self, adjustment):
+ display_distance = adjustment.get_value()
+ toggle_display_distance_end = self.settings.get_double('toggle-display-distance-end')
+ self.set_all_displays_distance_button.set_label(f"Use {display_distance}")
+ self.set_all_displays_distance_button.set_visible(display_distance != toggle_display_distance_end)
+
+ toggle_display_distance_start = self.settings.get_double('toggle-display-distance-start')
+ self.set_focused_display_distance_button.set_label(f"Use {display_distance}")
+ self.set_focused_display_distance_button.set_visible(display_distance != toggle_display_distance_start)
+
+ should_zoom_on_focus_be_enabled = display_distance < toggle_display_distance_end
+ if self.display_zoom_on_focus_switch.get_active() != should_zoom_on_focus_be_enabled:
+ self.display_zoom_on_focus_switch.set_active(should_zoom_on_focus_be_enabled)
+
+ def _set_focused_display_distance(self, distance):
+ self.focused_display_distance_label.set_markup(f"Focused display: {distance}")
+ self.settings.set_double('toggle-display-distance-start', distance)
+ self.set_focused_display_distance_button.set_visible(False)
+
+ def _set_all_displays_distance(self, distance):
+ self.all_displays_distance_label.set_markup(f"All displays: {distance}")
+ self.settings.set_double('toggle-display-distance-end', distance)
+ self.set_all_displays_distance_button.set_visible(False)
+ self.display_zoom_on_focus_switch.set_active(False)
+
+ def _on_set_all_displays_distance(self, *args):
+ distance = self.settings.get_double('display-distance')
+ focused_display_distance = self.settings.get_double('toggle-display-distance-start')
+ all_displays_distance = self.settings.get_double('toggle-display-distance-end')
+ if (distance < focused_display_distance):
+ self._set_focused_display_distance(distance)
+
+ self._set_all_displays_distance(distance)
+
+ def on_set_focused_display_distance(self, *args):
+ distance = self.settings.get_double('display-distance')
+ focused_display_distance = self.settings.get_double('toggle-display-distance-start')
+ all_displays_distance = self.settings.get_double('toggle-display-distance-end')
+ if (distance > all_displays_distance):
+ self._set_all_displays_distance(distance)
+
+ self._set_focused_display_distance(distance)
+
+ def _on_add_virtual_display(self, *args):
resolution = self.add_virtual_display_menu.get_active_id()
logger.info(f"Adding virtual display {resolution}")
diff --git a/ui/src/gtk/connected-device.ui b/ui/src/gtk/connected-device.ui
index 98389a7..60ed974 100644
--- a/ui/src/gtk/connected-device.ui
+++ b/ui/src/gtk/connected-device.ui
@@ -50,6 +50,18 @@
+
+
+
Virtual displays
@@ -69,7 +81,7 @@
- center
+ 3
@@ -89,7 +101,7 @@
add-virtual-display
list-add-symbolic
- center
+ 3
@@ -104,53 +116,97 @@
Adjustments
- Display distance
- Closer appears larger, further appears smaller. Controls depth when in widescreen mode.
-
-
- 3
- true
- 0
- 2
- 350
- false
-
-
- 0.2
- 2.5
- 0.01
- 1.05
-
-
-
- 0.2
- 1.0
- 2.5
-
-
-
-
-
-
-
- Display toggle distances
- Use the buttons to capture the current display distance for use with the keyboard shortcut.
- 2
+ Display distances
+ Set how close you want displays to appear.
- 30
- 150
- 30
+ vertical
+ 3
-
- toggle-display-distance-start
+
3
+ 20
+ 15
+ true
+ 0
+ 2
+ 350
+ false
+
+
+ 0.2
+ 2.5
+ 0.01
+ 1.05
+
+
+
+ closer
+ fullscreen
+ farther
+
-
- toggle-display-distance-end
+
+ 15
+
+
+
+
3
+ 5
+
+
+
+
+ 25
+ 1
+ 15
+
+
+ vertical
+ 6
+
+
+
+ 3
+
+
+
+
+ 0
+ set-all-displays-distance
+ 3
+
+ 20
+ 20
+
+
+
+
+
+
+ vertical
+ 6
+
+
+
+ 3
+
+
+
+
+ 0
+ set-all-displays-distance
+ 3
+
+ 20
+ 20
+
+
+
+
@@ -167,7 +223,7 @@
30
150
30
- center
+ 3
diff --git a/ui/src/gtk/no-device.ui b/ui/src/gtk/no-device.ui
index c7d6cad..9cbfa96 100644
--- a/ui/src/gtk/no-device.ui
+++ b/ui/src/gtk/no-device.ui
@@ -29,18 +29,6 @@
-
-
- Start in widescreen mode
- Widescreen mode is not supported for all glasses.
- 2
-
-
- 3
-
-
-
-
diff --git a/ui/src/nodevice.py b/ui/src/nodevice.py
index b36c656..878889f 100644
--- a/ui/src/nodevice.py
+++ b/ui/src/nodevice.py
@@ -10,7 +10,7 @@ class NoDevice(Gtk.Box):
__gtype_name__ = "NoDevice"
effect_enable_switch = Gtk.Template.Child()
- widescreen_mode_switch = Gtk.Template.Child()
+ # widescreen_mode_switch = Gtk.Template.Child()
def __init__(self):
super(Gtk.Box, self).__init__()
@@ -23,7 +23,7 @@ class NoDevice(Gtk.Box):
self.config_manager.connect('notify::breezy-desktop-enabled', self._handle_enabled_config)
self.effect_enable_switch.connect('notify::active', self._handle_switch_enabled_state)
- self.settings.bind('widescreen-mode', self.widescreen_mode_switch, 'active', Gio.SettingsBindFlags.DEFAULT)
+ # self.settings.bind('widescreen-mode', self.widescreen_mode_switch, 'active', Gio.SettingsBindFlags.DEFAULT)
self._handle_enabled_config(self.config_manager, None)
@@ -41,5 +41,5 @@ class NoDevice(Gtk.Box):
self.config_manager.set_property('breezy-desktop-enabled', requesting_enabled)
- def _on_widget_destroy(self, widget):
- self.settings.unbind('widescreen-mode', self.widescreen_mode_switch, 'active')
+ # def _on_widget_destroy(self, widget):
+ # self.settings.unbind('widescreen-mode', self.widescreen_mode_switch, 'active')
diff --git a/ui/src/window.py b/ui/src/window.py
index 375fa96..330e743 100644
--- a/ui/src/window.py
+++ b/ui/src/window.py
@@ -85,13 +85,13 @@ class BreezydesktopWindow(Gtk.ApplicationWindow):
for child in self.main_content:
self.main_content.remove(child)
- if not self._skip_verification and not verify_installation():
+ if self.settings.get_boolean('debug-no-device'):
+ self.main_content.append(self.connected_device)
+ self.connected_device.set_device_name('Fake device')
+ elif not self._skip_verification and not verify_installation():
self.main_content.append(self.failed_verification)
elif not ExtensionsManager.get_instance().is_installed():
self.main_content.append(self.no_extension)
- elif self.settings.get_boolean('debug-no-device'):
- self.main_content.append(self.connected_device)
- self.connected_device.set_device_name('Fake device')
elif not self.state_manager.driver_running:
self.main_content.append(self.no_driver)
elif not self.state_manager.license_present: