Update monitor manager integration to allow for virtual monitor detection, update effect to only show virtual monitors

This commit is contained in:
wheaney 2025-02-03 16:29:04 -08:00
parent 0a75f2f710
commit db3f59f7e7
3 changed files with 59 additions and 32 deletions

View File

@ -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'),

View File

@ -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;

View File

@ -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}`);