Add refresh rate and fast SBS mode switching settings
This commit is contained in:
parent
7369cb0551
commit
04edf2eecc
|
|
@ -1,5 +1,4 @@
|
|||
import Clutter from 'gi://Clutter';
|
||||
import GLib from 'gi://GLib';
|
||||
import Meta from 'gi://Meta';
|
||||
import * as PointerWatcher from 'resource:///org/gnome/shell/ui/pointerWatcher.js';
|
||||
import { MouseSpriteContent } from './cursor.js';
|
||||
|
|
|
|||
|
|
@ -71,6 +71,7 @@ export default class BreezyDesktopExtension extends Extension {
|
|||
this._monitor_manager = new MonitorManager({
|
||||
use_optimal_monitor_config: this.settings.get_boolean('use-optimal-monitor-config'),
|
||||
headset_as_primary: this.settings.get_boolean('headset-as-primary'),
|
||||
use_highest_refresh_rate: this.settings.get_boolean('use-highest-refresh-rate'),
|
||||
extension_path: this.path
|
||||
});
|
||||
this._monitor_manager.setChangeHook(this._handle_monitor_change.bind(this));
|
||||
|
|
@ -120,7 +121,7 @@ export default class BreezyDesktopExtension extends Extension {
|
|||
const target_monitor = this._monitor_manager.getMonitorPropertiesList()?.find(
|
||||
monitor => SUPPORTED_MONITOR_PRODUCTS.includes(monitor.product));
|
||||
if (target_monitor !== undefined) {
|
||||
Globals.logger.log_debug(`BreezyDesktopExtension _find_supported_monitor - Identified supported monitor: ${target_monitor.connector}`);
|
||||
Globals.logger.log(`Identified supported monitor: ${target_monitor.product} on ${target_monitor.connector}`);
|
||||
return {
|
||||
monitor: this._monitor_manager.getMonitors()[target_monitor.index],
|
||||
connector: target_monitor.connector,
|
||||
|
|
@ -151,8 +152,11 @@ export default class BreezyDesktopExtension extends Extension {
|
|||
// A false result means we'll expect _handle_monitor_change to be triggered, so active polling
|
||||
// can be disabled.
|
||||
_target_monitor_ready(target_monitor) {
|
||||
return target_monitor.is_dummy ||
|
||||
!this._monitor_manager.needsOptimalModeCheck(target_monitor.connector);
|
||||
if (target_monitor.is_dummy) return true;
|
||||
|
||||
const needs_sbs_mode_switch = this.settings.get_boolean('fast-sbs-mode-switching') &&
|
||||
this._needs_widescreen_monitor_update();
|
||||
return !needs_sbs_mode_switch && !this._monitor_manager.needsOptimalModeCheck(target_monitor.connector);
|
||||
}
|
||||
|
||||
_setup() {
|
||||
|
|
@ -213,7 +217,7 @@ export default class BreezyDesktopExtension extends Extension {
|
|||
const widescreen_setting_enabled = this.settings.get_boolean('widescreen-mode');
|
||||
if (widescreen_setting_enabled !== sbs_enabled) {
|
||||
Globals.logger.log_debug('BreezyDesktopExtension _needs_widescreen_monitor_update - true');
|
||||
this._write_control('sbs_mode', widescreen_setting_enabled ? 'enable' : 'disable');
|
||||
this._request_sbs_mode_change(widescreen_setting_enabled);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -259,7 +263,10 @@ export default class BreezyDesktopExtension extends Extension {
|
|||
});
|
||||
|
||||
this._update_follow_threshold(this.settings);
|
||||
this._update_widescreen_mode_from_settings(this.settings);
|
||||
|
||||
// this gets triggered before _effect_enable if in fast-sbs-mode-switching mode
|
||||
if (!this.settings.get_boolean('fast-sbs-mode-switching'))
|
||||
this._update_widescreen_mode_from_settings(this.settings);
|
||||
|
||||
this._widescreen_mode_effect_state_connection = this._xr_effect.connect('notify::widescreen-mode-state', this._update_widescreen_mode_from_state.bind(this));
|
||||
this._supported_device_detected_connected = this._xr_effect.connect('notify::supported-device-detected', this._handle_supported_device_change.bind(this));
|
||||
|
|
@ -362,16 +369,41 @@ export default class BreezyDesktopExtension extends Extension {
|
|||
if (value !== undefined) this._write_control('breezy_desktop_follow_threshold', value);
|
||||
}
|
||||
|
||||
// requests sbs_mode change and monitors to ensure the state reflects the setting
|
||||
_request_sbs_mode_change(value) {
|
||||
this._write_control('sbs_mode', value ? 'enable' : 'disable');
|
||||
if (!this._sbs_mode_update_timeout) {
|
||||
var attempts = 0;
|
||||
this._sbs_mode_update_timeout = GLib.timeout_add(GLib.PRIORITY_DEFAULT, 10000, (() => {
|
||||
if (attempts++ < 3) {
|
||||
this._write_control('sbs_mode', value ? 'enable' : 'disable');
|
||||
return GLib.SOURCE_CONTINUE;
|
||||
}
|
||||
|
||||
// the state never updated to reflect our request, revert the setting
|
||||
this.settings.set_boolean('widescreen-mode', !value);
|
||||
this._sbs_mode_update_timeout = undefined;
|
||||
return GLib.SOURCE_REMOVE;
|
||||
}).bind(this));
|
||||
}
|
||||
}
|
||||
|
||||
_update_widescreen_mode_from_settings(settings, event) {
|
||||
const value = settings.get_boolean('widescreen-mode');
|
||||
Globals.logger.log_debug(`BreezyDesktopExtension _update_widescreen_mode_from_settings ${value}`);
|
||||
if (value !== undefined && value !== this._xr_effect.widescreen_mode_state)
|
||||
this._write_control('sbs_mode', value ? 'enable' : 'disable');
|
||||
else
|
||||
if (value !== undefined && value !== this._xr_effect.widescreen_mode_state) {
|
||||
this._request_sbs_mode_change(value);
|
||||
} else
|
||||
Globals.logger.log_debug('effect.widescreen_mode_state already matched setting');
|
||||
}
|
||||
|
||||
_update_widescreen_mode_from_state(effect, _pspec) {
|
||||
// kill our state checker if it's running
|
||||
if (this._sbs_mode_update_timeout) {
|
||||
GLib.source_remove(this._sbs_mode_update_timeout);
|
||||
this._sbs_mode_update_timeout = undefined;
|
||||
}
|
||||
|
||||
const value = effect.widescreen_mode_state;
|
||||
Globals.logger.log_debug(`BreezyDesktopExtension _update_widescreen_mode_from_state ${value}`);
|
||||
if (value !== this.settings.get_boolean('widescreen-mode'))
|
||||
|
|
|
|||
|
|
@ -86,7 +86,7 @@ function getMonitorConfig(displayConfigProxy, callback) {
|
|||
}
|
||||
|
||||
// triggers callback with true result if an an async monitor config change was triggered, false if no config change needed
|
||||
function performOptimalModeCheck(displayConfigProxy, connectorName, headsetAsPrimary, callback) {
|
||||
function performOptimalModeCheck(displayConfigProxy, connectorName, headsetAsPrimary, useHighestRefreshRate, callback) {
|
||||
Globals.logger.log_debug(`monitormanager.js performOptimalModeCheck for ${connectorName}`);
|
||||
displayConfigProxy.GetCurrentStateRemote((result, error) => {
|
||||
if (error) {
|
||||
|
|
@ -101,10 +101,19 @@ function performOptimalModeCheck(displayConfigProxy, connectorName, headsetAsPri
|
|||
let monitorToModeIdMap = {};
|
||||
let bestFitMode = undefined;
|
||||
for (let monitor of monitors) {
|
||||
const [details, modes, monProperties] = monitor;
|
||||
const [details, availableModes, monProperties] = monitor;
|
||||
const [connector, vendor, product, monitorSerial] = details;
|
||||
const isOurMonitor = connector == connectorName;
|
||||
if (isOurMonitor) ourMonitor = monitor;
|
||||
let modes = availableModes;
|
||||
if (isOurMonitor) {
|
||||
ourMonitor = monitor;
|
||||
if (!useHighestRefreshRate) {
|
||||
const currentMode = modes.find((mode) => !!mode[6]['is-current']);
|
||||
|
||||
// filter modes to only include the current refresh rate
|
||||
modes = availableModes.filter((mode) => mode[3] === currentMode[3]);
|
||||
}
|
||||
}
|
||||
|
||||
for (let mode of modes) {
|
||||
const [modeId, width, height, refreshRate, preferredScale, supportedScales, modeProperites] = mode;
|
||||
|
|
@ -199,6 +208,13 @@ export const MonitorManager = GObject.registerClass({
|
|||
GObject.ParamFlags.READWRITE,
|
||||
true
|
||||
),
|
||||
'use-highest-refresh-rate': GObject.ParamSpec.boolean(
|
||||
'use-highest-refresh-rate',
|
||||
'Use highest refresh rate',
|
||||
'Set the highest refresh rate which choosing optimal configs',
|
||||
GObject.ParamFlags.READWRITE,
|
||||
true
|
||||
),
|
||||
'headset-as-primary': GObject.ParamSpec.boolean(
|
||||
'headset-as-primary',
|
||||
'Use headset as primary monitor',
|
||||
|
|
@ -272,7 +288,7 @@ export const MonitorManager = GObject.registerClass({
|
|||
}
|
||||
|
||||
if (this._needsConfigCheck) {
|
||||
performOptimalModeCheck(this._displayConfigProxy, monitorConnector, this.headset_as_primary, ((configChanged, error) => {
|
||||
performOptimalModeCheck(this._displayConfigProxy, monitorConnector, this.headset_as_primary, this.use_highest_refresh_rate, ((configChanged, error) => {
|
||||
this._needsConfigCheck = false;
|
||||
if (error) {
|
||||
Globals.logger.log(`Failed to switch to optimal mode for monitor ${monitorConnector}: ${error}`);
|
||||
|
|
@ -309,7 +325,7 @@ export const MonitorManager = GObject.registerClass({
|
|||
for (let i = 0; i < result.length; i++) {
|
||||
const [monitorName, connectorName, vendor, product, serial, refreshRate] = result[i];
|
||||
const monitorIndex = this._backendManager.get_monitor_for_connector(connectorName);
|
||||
Globals.logger.log(`Found monitor ${monitorName}, vendor ${vendor}, product ${product}, serial ${serial}, connector ${connectorName}, index ${monitorIndex}`);
|
||||
Globals.logger.log_debug(`Found monitor ${monitorName}, vendor ${vendor}, product ${product}, serial ${serial}, connector ${connectorName}, index ${monitorIndex}`);
|
||||
if (monitorIndex >= 0) {
|
||||
monitorProperties[monitorIndex] = {
|
||||
index: monitorIndex,
|
||||
|
|
|
|||
|
|
@ -16,12 +16,12 @@ check_command "flatpak-builder"
|
|||
# https://stackoverflow.com/a/246128
|
||||
SCRIPT_DIR=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" &>/dev/null && pwd)
|
||||
|
||||
TMP_DIR=$(mktemp -d -t breezy-ui-flatpak-XXXXXXXXXX)
|
||||
TMP_DIR=$(mktemp -d -t --tmpdir=$SCRIPT_DIR/.. breezy-ui-flatpak-XXXXXXXXXX)
|
||||
OUT_DIR=$SCRIPT_DIR/../out
|
||||
rm -rf $OUT_DIR
|
||||
mkdir -p $OUT_DIR
|
||||
|
||||
flatpak-builder --force-clean $TMP_DIR/build $SCRIPT_DIR/../com.xronlinux.BreezyDesktop.json
|
||||
flatpak-builder --force-clean --delete-build-dirs $TMP_DIR/build $SCRIPT_DIR/../com.xronlinux.BreezyDesktop.json
|
||||
flatpak build-export $TMP_DIR/export $TMP_DIR/build
|
||||
flatpak build-bundle $TMP_DIR/export $OUT_DIR/com.xronlinux.BreezyDesktop.flatpak com.xronlinux.BreezyDesktop --runtime-repo=https://flathub.org/repo/flathub.flatpakrepo
|
||||
|
||||
|
|
|
|||
|
|
@ -118,6 +118,24 @@
|
|||
Automatically set the headset as the primary display upon connection
|
||||
</description>
|
||||
</key>
|
||||
<key name="use-highest-refresh-rate" type="b">
|
||||
<default>
|
||||
true
|
||||
</default>
|
||||
<summary>Use highest refresh rate</summary>
|
||||
<description>
|
||||
Automatically set the highest refresh rate upon connection
|
||||
</description>
|
||||
</key>
|
||||
<key name="fast-sbs-mode-switching" type="b">
|
||||
<default>
|
||||
true
|
||||
</default>
|
||||
<summary>Fast SBS mode switching</summary>
|
||||
<description>
|
||||
Enable fast SBS mode switching
|
||||
</description>
|
||||
</key>
|
||||
<key name="disable-anti-aliasing" type="b">
|
||||
<default>
|
||||
false
|
||||
|
|
|
|||
|
|
@ -3,7 +3,13 @@
|
|||
<id>com.xronlinux.BreezyDesktop.desktop</id>
|
||||
<metadata_license>CC0-1.0</metadata_license>
|
||||
<project_license>GPL-3.0-or-later</project_license>
|
||||
<name>Breezy Desktop</name>
|
||||
<summary>XR Desktop Control Panel</summary>
|
||||
<description>
|
||||
<p>No description</p>
|
||||
<p>XR Desktop Control Panel</p>
|
||||
</description>
|
||||
<categories>
|
||||
<category>Office</category>
|
||||
<category>Development</category>
|
||||
</categories>
|
||||
</component>
|
||||
|
|
|
|||
|
|
@ -31,6 +31,8 @@ class ConnectedDevice(Gtk.Box):
|
|||
toggle_follow_shortcut_label = Gtk.Template.Child()
|
||||
headset_as_primary_switch = Gtk.Template.Child()
|
||||
use_optimal_monitor_config_switch = Gtk.Template.Child()
|
||||
use_highest_refresh_rate_switch = Gtk.Template.Child()
|
||||
fast_sbs_mode_switch = Gtk.Template.Child()
|
||||
movement_look_ahead_scale = Gtk.Template.Child()
|
||||
movement_look_ahead_adjustment = Gtk.Template.Child()
|
||||
|
||||
|
|
@ -52,6 +54,8 @@ class ConnectedDevice(Gtk.Box):
|
|||
self.reassign_toggle_follow_shortcut_button,
|
||||
self.headset_as_primary_switch,
|
||||
self.use_optimal_monitor_config_switch,
|
||||
self.use_highest_refresh_rate_switch,
|
||||
self.fast_sbs_mode_switch,
|
||||
self.movement_look_ahead_scale
|
||||
]
|
||||
|
||||
|
|
@ -66,6 +70,8 @@ class ConnectedDevice(Gtk.Box):
|
|||
self.settings.bind('curved-display', self.curved_display_switch, 'active', Gio.SettingsBindFlags.DEFAULT)
|
||||
self.settings.bind('headset-as-primary', self.headset_as_primary_switch, 'active', Gio.SettingsBindFlags.DEFAULT)
|
||||
self.settings.bind('use-optimal-monitor-config', self.use_optimal_monitor_config_switch, 'active', Gio.SettingsBindFlags.DEFAULT)
|
||||
self.settings.bind('use-highest-refresh-rate', self.use_highest_refresh_rate_switch, 'active', Gio.SettingsBindFlags.DEFAULT)
|
||||
self.settings.bind('fast-sbs-mode-switching', self.fast_sbs_mode_switch, 'active', Gio.SettingsBindFlags.DEFAULT)
|
||||
self.settings.bind('look-ahead-override', self.movement_look_ahead_adjustment, 'value', Gio.SettingsBindFlags.DEFAULT)
|
||||
|
||||
bind_shortcut_settings(self.get_parent(), [
|
||||
|
|
@ -136,8 +142,10 @@ class ConnectedDevice(Gtk.Box):
|
|||
|
||||
def _refresh_use_optimal_monitor_config(self, switch, param):
|
||||
self.headset_as_primary_switch.set_sensitive(switch.get_active())
|
||||
self.use_highest_refresh_rate_switch.set_sensitive(switch.get_active())
|
||||
if not switch.get_active():
|
||||
self.headset_as_primary_switch.set_active(False)
|
||||
self.use_highest_refresh_rate_switch.set_active(False)
|
||||
|
||||
def set_device_name(self, name):
|
||||
self.device_label.set_markup(f"<b>{name}</b>")
|
||||
|
|
|
|||
|
|
@ -328,6 +328,17 @@
|
|||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="AdwActionRow">
|
||||
<property name="title" translatable="true">Use highest refresh rate</property>
|
||||
<property name="subtitle" translatable="true">Refresh rate may affect performance, disable this to set it manually.</property>
|
||||
<child>
|
||||
<object class="GtkSwitch" id="use_highest_refresh_rate_switch">
|
||||
<property name="valign">3</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="AdwActionRow">
|
||||
<property name="title" translatable="true">Always primary display</property>
|
||||
|
|
@ -339,6 +350,17 @@
|
|||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="AdwActionRow">
|
||||
<property name="title" translatable="true">Fast SBS mode switching</property>
|
||||
<property name="subtitle" translatable="true">Switches glasses to SBS mode immediately when plugged in, if widescreen mode is on. May cause instability.</property>
|
||||
<child>
|
||||
<object class="GtkSwitch" id="fast_sbs_mode_switch">
|
||||
<property name="valign">3</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="AdwActionRow">
|
||||
<property name="title" translatable="true">Movement look-ahead</property>
|
||||
|
|
|
|||
Loading…
Reference in New Issue