diff --git a/gnome/src/extension.js b/gnome/src/extension.js index d558708..99b0b41 100644 --- a/gnome/src/extension.js +++ b/gnome/src/extension.js @@ -17,6 +17,7 @@ import {Extension} from 'resource:///org/gnome/shell/extensions/extension.js'; import * as Main from 'resource:///org/gnome/shell/ui/main.js'; const NESTED_MONITOR_PRODUCT = 'MetaMonitor'; +const VIRTUAL_MONITOR_PRODUCT = 'Virtual remote monitor'; const SUPPORTED_MONITOR_PRODUCTS = [ 'VITURE', 'nreal air', @@ -137,7 +138,29 @@ export default class BreezyDesktopExtension extends Extension { }).bind(this)); } + _find_virtual_monitors() { + try { + Globals.logger.log_debug('BreezyDesktopExtension _find_virtual_monitors'); + const virtual_monitors = this._monitor_manager.getMonitorPropertiesList()?.filter( + monitor => monitor && monitor.product === VIRTUAL_MONITOR_PRODUCT); + if (virtual_monitors.length > 0) { + Globals.logger.log(`Found ${virtual_monitors.length} virtual monitors`); + return virtual_monitors.map(monitor => { + return this._monitor_manager.getMonitors()[monitor.index]; + }); + } + + Globals.logger.log_debug('BreezyDesktopExtension _find_virtual_monitors - No virtual monitors found'); + } catch (e) { + Globals.logger.log(`[ERROR] BreezyDesktopExtension _find_virtual_monitors ${e.message}\n${e.stack}`) + } + + return []; + } + _find_supported_monitor() { + if (!this._monitor_manager.getMonitorPropertiesList()) return null; + try { Globals.logger.log_debug('BreezyDesktopExtension _find_supported_monitor'); const target_monitor = this._monitor_manager.getMonitorPropertiesList()?.find( @@ -149,7 +172,8 @@ export default class BreezyDesktopExtension extends Extension { monitor: this._monitor_manager.getMonitors()[target_monitor.index], connector: target_monitor.connector, refreshRate: target_monitor.refreshRate, - is_dummy: target_monitor.product === NESTED_MONITOR_PRODUCT + is_dummy: target_monitor.product === NESTED_MONITOR_PRODUCT, + is_virtual: target_monitor.product === VIRTUAL_MONITOR_PRODUCT }; } @@ -247,7 +271,7 @@ export default class BreezyDesktopExtension extends Extension { // const textureSourceActor = Main.layoutManager.uiGroup; Globals.data_stream.refresh_data(); this._overlay_content = new VirtualMonitorsActor({ - monitors: [], + monitors: this._find_virtual_monitors(), fov_degrees: 46.0, target_monitor: targetMonitor, display_distance: this.settings.get_double('display-distance'), diff --git a/gnome/src/monitormanager.js b/gnome/src/monitormanager.js index 3d45e88..84d0aec 100644 --- a/gnome/src/monitormanager.js +++ b/gnome/src/monitormanager.js @@ -54,34 +54,28 @@ export function newDisplayConfig(extPath, callback) { } function getMonitorConfig(displayConfigProxy, callback) { - displayConfigProxy.GetResourcesRemote((result, error) => { + displayConfigProxy.GetCurrentStateRemote((result, error) => { if (error) { - callback(null, `GetResourcesRemote failed: ${error}`); + callback(null, `GetCurrentState failed: ${error}`); } else { - Globals.logger.log_debug(`monitormanager.js getMonitorConfig GetResources result: ${JSON.stringify(result)}`); - const monitors = []; - for (let i = 0; i < result[2].length; i++) { - const output = result[2][i]; - if (output.length <= 7) { - callback(null, 'Cannot get DisplayConfig: No properties on output #' + i); - return; - } - const props = output[7]; - const displayName = props['display-name'].get_string()[0]; - const connectorName = output[4]; - if (!displayName || displayName == '') { - const displayName = 'Monitor on output ' + connectorName; - } - const vendor = props['vendor'].get_string()[0]; - const product = props['product'].get_string()[0]; - const serial = props['serial'].get_string()[0]; + Globals.logger.log_debug(`monitormanager.js getMonitorConfig GetCurrentState result: ${JSON.stringify(result)}`); + + const allMonitors = []; + const [serial, monitors, logicalMonitors, properties] = result; + for (let monitor of monitors) { + const [details, modes, monProperties] = monitor; + const [connector, vendor, product, monitorSerial] = details; + const displayName = monProperties['display-name'].get_string()[0]; - // grab refresh rate from the modes array - const refreshRate = result[3][i][4]; - - monitors.push([displayName, connectorName, vendor, product, serial, refreshRate]); + for (let mode of modes) { + const [modeId, width, height, refreshRate, preferredScale, supportedScales, modeProperites] = mode; + const isCurrent = !!modeProperites['is-current']; + if (isCurrent) { + allMonitors.push([displayName, connector, vendor, product, serial, refreshRate]); + } + } } - callback(monitors, null); + callback(allMonitors, null); } }); } @@ -289,6 +283,7 @@ export const MonitorManager = GObject.registerClass({ // help prevent certain actions from taking place multiple times in the event of rapid monitor updates this._asyncRequestsInFlight = 0; this._configCheckRequestsCount = 0; + this._enabled = false; } enable() { @@ -303,12 +298,14 @@ export const MonitorManager = GObject.registerClass({ }).bind(this)); this._monitorsChangedConnection = Main.layoutManager.connect('monitors-changed', this._on_monitors_change.bind(this)); + this._enabled = true; } disable() { Globals.logger.log_debug('MonitorManager disable'); Main.layoutManager.disconnect(this._monitorsChangedConnection); + this._enabled = false; this._monitorsChangedConnection = null; this._displayConfigProxy = null; this._backendManager = null; @@ -384,6 +381,8 @@ export const MonitorManager = GObject.registerClass({ } _on_monitors_change() { + if (!this._enabled) return; + Globals.logger.log_debug('MonitorManager _on_monitors_change'); if (this._displayConfigProxy == null) { return; diff --git a/gnome/src/virtualmonitorsactor.js b/gnome/src/virtualmonitorsactor.js index 6d060b9..f66bdf9 100644 --- a/gnome/src/virtualmonitorsactor.js +++ b/gnome/src/virtualmonitorsactor.js @@ -629,6 +629,10 @@ export const VirtualMonitorsActor = GObject.registerClass({ this.width = this.target_monitor.width; this.height = this.target_monitor.height; this._frametime_ms = Math.floor(1000 / (this.target_framerate ?? 60.0)); + this._all_monitors = [ + this.target_monitor, + ...this.monitors + ]; } renderMonitors() { @@ -638,7 +642,7 @@ export const VirtualMonitorsActor = GObject.registerClass({ widthPixels: this.width, heightPixels: this.height }, - Main.layoutManager.monitors.map(monitor => ({ + this._all_monitors.map(monitor => ({ x: monitor.x, y: monitor.y, width: monitor.width, @@ -653,14 +657,14 @@ export const VirtualMonitorsActor = GObject.registerClass({ const length = Math.sqrt(vector[0] * vector[0] + vector[1] * vector[1] + vector[2] * vector[2]); return [vector[0] / length, vector[1] / length, vector[2] / length]; }); - const monitors = Main.layoutManager.monitors; + const monitors = this._all_monitors; const minMonitorX = Math.min(...monitors.map(monitor => monitor.x)); const maxMonitorX = Math.max(...monitors.map(monitor => monitor.x + monitor.width)); const minMonitorY = Math.min(...monitors.map(monitor => monitor.y)); const maxMonitorY = Math.max(...monitors.map(monitor => monitor.y + monitor.height)); - const displayWidth = maxMonitorX - minMonitorX; - const displayHeight = maxMonitorY - minMonitorY; + const displayWidth = global.stage.width; + const displayHeight = global.stage.height; const actorToDisplayRatios = [ displayWidth / this.width, displayHeight / this.height @@ -670,8 +674,8 @@ export const VirtualMonitorsActor = GObject.registerClass({ const actorMidX = this.target_monitor.x + this.width / 2; const actorMidY = this.target_monitor.y + this.height / 2; const actorToDisplayOffsets = [ - (displayWidth / 2 - (actorMidX - minMonitorX)) * 2 / this.width, - (displayHeight / 2 - (actorMidY - minMonitorY)) * 2 / this.height + (displayWidth / 2 - (actorMidX - global.stage.x)) * 2 / this.width, + (displayHeight / 2 - (actorMidY - global.stage.y)) * 2 / this.height ]; Globals.logger.log_debug(`\t\t\tActor to display ratios: ${actorToDisplayRatios}, offsets: ${actorToDisplayOffsets}`);