From d97069e18f9432e0bf9b64fb5970bbaf6d9043c2 Mon Sep 17 00:00:00 2001 From: wheaney <42350981+wheaney@users.noreply.github.com> Date: Sun, 28 Jul 2024 09:14:52 -0700 Subject: [PATCH 1/7] Pull in setup messaging fixes --- gnome/bin/setup | 2 +- modules/XRLinuxDriver | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/gnome/bin/setup b/gnome/bin/setup index 616dc42..7ee291a 100755 --- a/gnome/bin/setup +++ b/gnome/bin/setup @@ -4,7 +4,7 @@ set -e check_command() { if ! command -v "$1" &>/dev/null; then - echo "Please install \"$1\" and make sure it's available in your \$PATH" + echo "Please install \"$1\" and make sure it's available in your \$PATH, then rerun the setup." exit 1 fi } diff --git a/modules/XRLinuxDriver b/modules/XRLinuxDriver index 4ce360a..7afbc25 160000 --- a/modules/XRLinuxDriver +++ b/modules/XRLinuxDriver @@ -1 +1 @@ -Subproject commit 4ce360a936937e8dd0ebd54a337fec54bb38f497 +Subproject commit 7afbc258e71a7efde015394820c60c24cc785773 From cb3777e72a9649c990107e7aa570e187f311b3cf Mon Sep 17 00:00:00 2001 From: Wayne Heaney <42350981+wheaney@users.noreply.github.com> Date: Sun, 28 Jul 2024 09:22:23 -0700 Subject: [PATCH 2/7] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 92ac561..75a32c7 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ There are two installations at the moment. **Note: Only install one of these at * [Breezy Vulkan](#breezy-vulkan) primarily for gaming but would work with pretty much any application that uses Vulkan rendering. ## Breezy GNOME -Breezy GNOME is a virtual workspace solution for Linux desktops that use the GNOME desktop environment (supports GNOME versions 42-46 on an x86_64 system); see [non-GNOME setup](#non-gnome-setup) if you want to try it without a GNOME desktop environment. It currently supports one virtual monitor and multiple physical monitors, but it will soon support multiple virtual monitors. See [upcoming features](#upcoming-features) for more improvements on the horizon. +Breezy GNOME is a virtual workspace solution for Linux desktops that use the GNOME desktop environment supports GNOME versions 42-46; see [non-GNOME setup](#non-gnome-setup) if you want to try it without a GNOME desktop environment. It currently supports one virtual monitor and multiple physical monitors, but it will soon support multiple virtual monitors. See [upcoming features](#upcoming-features) for more improvements on the horizon. ### GNOME Setup From e9e5d3864a8e1e646d90b85ff82fe72c96eae54a Mon Sep 17 00:00:00 2001 From: Wayne Heaney <42350981+wheaney@users.noreply.github.com> Date: Sun, 28 Jul 2024 13:06:07 -0700 Subject: [PATCH 3/7] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 75a32c7..c303c23 100644 --- a/README.md +++ b/README.md @@ -31,7 +31,7 @@ Breezy GNOME is in AUR (but not pacman, yet). To install, run these commands fro 1. Download the Breezy GNOME [setup script](https://github.com/wheaney/breezy-desktop/releases/latest/download/breezy_gnome_setup) and set the execute flag (e.g. from the terminal: `chmod +x ~/Downloads/breezy_gnome_setup`) 2. Run the setup script: * For **GNOME 45+**: `~/Downloads/breezy_gnome_setup` - * For **GNOME 42-44**: `~/Downloads/breezy_gnome_setup --tag gnome-44-max-beta-2` + * For **GNOME 42-44**: `~/Downloads/breezy_gnome_setup --tag gnome-44-max` ### Non-GNOME Setup A workable solution (with some [QoL improvements needed](#upcoming-features)) is to use your preferred desktop environment with a GNOME window open in nested mode. To do this: From 6ea84e275fd5331fb2ef4ed6ebe42f9c0e005ed1 Mon Sep 17 00:00:00 2001 From: wheaney <42350981+wheaney@users.noreply.github.com> Date: Sun, 28 Jul 2024 14:26:38 -0700 Subject: [PATCH 4/7] Pull in driver with monitoring of IMU data --- modules/XRLinuxDriver | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/XRLinuxDriver b/modules/XRLinuxDriver index 7afbc25..ee44863 160000 --- a/modules/XRLinuxDriver +++ b/modules/XRLinuxDriver @@ -1 +1 @@ -Subproject commit 7afbc258e71a7efde015394820c60c24cc785773 +Subproject commit ee44863cf24310e6e34acbec668499f45836c1f7 From 0238cd779071aa3f807c536332e304bca7bf7951 Mon Sep 17 00:00:00 2001 From: wheaney <42350981+wheaney@users.noreply.github.com> Date: Sun, 28 Jul 2024 23:30:30 -0700 Subject: [PATCH 5/7] Pull in driver timestamp fix --- modules/XRLinuxDriver | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/XRLinuxDriver b/modules/XRLinuxDriver index ee44863..48d5153 160000 --- a/modules/XRLinuxDriver +++ b/modules/XRLinuxDriver @@ -1 +1 @@ -Subproject commit ee44863cf24310e6e34acbec668499f45836c1f7 +Subproject commit 48d515323e4e276a3e2736078ec0434cd5d64231 From 1b14468d86a6e620982c30d492f2dba59a4812ad Mon Sep 17 00:00:00 2001 From: wheaney <42350981+wheaney@users.noreply.github.com> Date: Mon, 29 Jul 2024 13:49:39 -0700 Subject: [PATCH 6/7] Update optimal config logic to shift other monitors that would be affected by a change in screen resolution --- gnome/src/extension.js | 26 ++++++++++++++++---- gnome/src/monitormanager.js | 47 +++++++++++++++++++++++++++++++------ 2 files changed, 61 insertions(+), 12 deletions(-) diff --git a/gnome/src/extension.js b/gnome/src/extension.js index f78c5a6..84d00a4 100644 --- a/gnome/src/extension.js +++ b/gnome/src/extension.js @@ -101,8 +101,7 @@ export default class BreezyDesktopExtension extends Extension { return GLib.SOURCE_REMOVE; } - const is_driver_running = this._check_driver_running(); - if (is_driver_running && target_monitor) { + if (this._check_driver_running() && target_monitor) { // Don't enable the effect yet if monitor updates are needed. // _setup will be triggered again since a !ready result means it will trigger monitor changes, // so we can remove this timeout_add no matter what. @@ -221,7 +220,7 @@ export default class BreezyDesktopExtension extends Extension { _needs_widescreen_monitor_update() { Globals.logger.log_debug('BreezyDesktopExtension _needs_widescreen_monitor_update'); - const state = this._read_state(['sbs_mode_enabled']); + const state = this._read_state(); const sbs_enabled = state['sbs_mode_enabled'] === 'true'; const widescreen_setting_enabled = this.settings.get_boolean('widescreen-mode'); if (widescreen_setting_enabled !== sbs_enabled) { @@ -249,6 +248,8 @@ export default class BreezyDesktopExtension extends Extension { this._overlay.opacity = 255; this._overlay.set_position(targetMonitor.x, targetMonitor.y); this._overlay.set_size(targetMonitor.width, targetMonitor.height); + Globals.logger.log_debug(`BreezyDesktopExtension _effect_enable overlay size: \ + ${targetMonitor.width}x${targetMonitor.height} at ${targetMonitor.x},${targetMonitor.y}`); const overlayContent = new Clutter.Actor({clip_to_allocation: true}); const uiClone = new Clutter.Clone({ source: Main.layoutManager.uiGroup, clip_to_allocation: true }); @@ -349,7 +350,7 @@ export default class BreezyDesktopExtension extends Extension { } } - _read_state(keys) { + _read_state() { const state = {}; try { const file = Gio.file_new_for_path('/dev/shm/xr_driver_state'); @@ -364,7 +365,7 @@ export default class BreezyDesktopExtension extends Extension { const lines = contents.split('\n'); for (const line of lines) { const [k, v] = line.split('='); - if (keys.includes(k)) state[k] = v; + state[k] = v; } } } @@ -388,10 +389,25 @@ export default class BreezyDesktopExtension extends Extension { // requests sbs_mode change and monitors to ensure the state reflects the setting _request_sbs_mode_change(value) { + Globals.logger.log_debug(`BreezyDesktopExtension _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, 3000, (() => { + const state = this._read_state(); + const sbs_enabled = state['sbs_mode_enabled'] === 'true'; + if (sbs_enabled === value) { + Globals.logger.log_debug('BreezyDesktopExtension _request_sbs_mode_change - successfully updated'); + this._sbs_mode_update_timeout = undefined; + + if (this.settings.get_boolean('fast-sbs-mode-switching')) { + // setup and polling were halted if this is enabled, so we have to re-trigger setup + this._setup(); + } + + return GLib.SOURCE_REMOVE; + } + if (attempts++ < 3) { this._write_control('sbs_mode', value ? 'enable' : 'disable'); return GLib.SOURCE_CONTINUE; diff --git a/gnome/src/monitormanager.js b/gnome/src/monitormanager.js index 025a6c8..ca8a6a5 100644 --- a/gnome/src/monitormanager.js +++ b/gnome/src/monitormanager.js @@ -107,7 +107,7 @@ function performOptimalModeCheck(displayConfigProxy, connectorName, headsetAsPri // iterate over all monitors at least once, collecting the best fit mode for our monitor, and mode information // for each monitor let ourMonitor = undefined; - let monitorToModeIdMap = {}; + let monitorToCurrentModeMap = {}; let bestFitMode = undefined; const skipScaleUpdate = !!properties['global-scale-required']; for (let monitor of monitors) { @@ -128,7 +128,7 @@ function performOptimalModeCheck(displayConfigProxy, connectorName, headsetAsPri for (let mode of modes) { const [modeId, width, height, refreshRate, preferredScale, supportedScales, modeProperites] = mode; const isCurrent = !!modeProperites['is-current']; - if (isCurrent) monitorToModeIdMap[connector] = modeId; + if (isCurrent) monitorToCurrentModeMap[connector] = mode; if (isOurMonitor && (!bestFitMode || ( width >= bestFitMode.width && @@ -144,8 +144,7 @@ function performOptimalModeCheck(displayConfigProxy, connectorName, headsetAsPri width, height, refreshRate, - bestScale, - isCurrent + bestScale }; } } @@ -154,6 +153,14 @@ function performOptimalModeCheck(displayConfigProxy, connectorName, headsetAsPri if (!!ourMonitor) { let anyMonitorsChanged = false; if (!!bestFitMode) { + // this will hold how much the width of the monitor has changed, + // and what range of y values is affected + let deltaX = 0; + let rangeY = [0, 0]; + + // sort logicalMonitors by x ascending, so we can tell if any are affected by a width change + logicalMonitors.sort((a, b) => a[0] - b[0]); + // map from original logical monitors schema to a(iiduba(ssa{sv})) for ApplyMonitorsConfig call const updatedLogicalMonitors = logicalMonitors.map((logicalMonitor) => { const [x, y, scale, transform, primary, monitors, logMonProperties] = logicalMonitor; @@ -164,8 +171,29 @@ function performOptimalModeCheck(displayConfigProxy, connectorName, headsetAsPri // there can only be one primary monitor, so we need to set all other monitors to not primary and glasses to primary, // if headsetAsPrimary is true anyMonitorsChanged |= headsetAsPrimary && ((hasOurMonitor && !primary) || (!hasOurMonitor && primary)); + + // we need to figure out if the deltaX applies to this logical monitor, + // i.e. if it is within the same row as our monitor and to the right of it + let thisDeltaX = deltaX; + if (thisDeltaX !== 0) { + // find the monitor with the largest height + const maxMonitorHeight = monitors.reduce((maxHeight, monitor) => { + const monitorConnector = monitor[0]; + const currentMode = monitorToCurrentModeMap[monitorConnector]; + const currentHeight = currentMode[2]; + return Math.max(maxHeight, currentHeight); + }, 0); + + if (y >= rangeY[1] || y + maxMonitorHeight <= rangeY[0]) { + // monitors outside the y range are not affected by the width change + thisDeltaX = 0; + } else { + anyMonitorsChanged = true; + } + } + return [ - x, + x + thisDeltaX, y, newScale, transform, @@ -173,10 +201,15 @@ function performOptimalModeCheck(displayConfigProxy, connectorName, headsetAsPri monitors.map((monitor) => { const monitorConnector = monitor[0]; const isOurMonitor = monitorConnector === connectorName; - anyMonitorsChanged |= isOurMonitor && !bestFitMode.isCurrent; + const [currentModeId, currentWidth, currentHeight] = monitorToCurrentModeMap[monitorConnector]; + if (isOurMonitor) { + deltaX = bestFitMode.width - currentWidth; + rangeY = [y, y + currentHeight]; + } + anyMonitorsChanged |= isOurMonitor && bestFitMode.modeId !== currentModeId; return [ monitorConnector, - isOurMonitor ? bestFitMode.modeId : monitorToModeIdMap[monitorConnector], + isOurMonitor ? bestFitMode.modeId : currentModeId, {} // properties ]; }) From 99091f77dab56ad2eb3710411a3f359eca4495b8 Mon Sep 17 00:00:00 2001 From: wheaney <42350981+wheaney@users.noreply.github.com> Date: Mon, 29 Jul 2024 17:54:44 -0700 Subject: [PATCH 7/7] Make VITURE more reliable --- modules/XRLinuxDriver | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/XRLinuxDriver b/modules/XRLinuxDriver index 48d5153..6442187 160000 --- a/modules/XRLinuxDriver +++ b/modules/XRLinuxDriver @@ -1 +1 @@ -Subproject commit 48d515323e4e276a3e2736078ec0434cd5d64231 +Subproject commit 64421876bf080ebf36598fe9a044ad77892f5880