Optimize monitor focus checking, fix toggle XR effect not working when disabled, v2.1.1
This commit is contained in:
parent
618dceaf10
commit
fb38c89e41
|
|
@ -94,6 +94,8 @@ export default class BreezyDesktopExtension extends Extension {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this._add_settings_keybinding('toggle-xr-effect-shortcut', this._toggle_xr_effect.bind(this));
|
||||||
|
|
||||||
this._setup();
|
this._setup();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
Globals.logger.log(`[ERROR] BreezyDesktopExtension enable ${e.message}\n${e.stack}`);
|
Globals.logger.log(`[ERROR] BreezyDesktopExtension enable ${e.message}\n${e.stack}`);
|
||||||
|
|
@ -306,7 +308,6 @@ export default class BreezyDesktopExtension extends Extension {
|
||||||
Meta.disable_unredirect_for_display(global.display);
|
Meta.disable_unredirect_for_display(global.display);
|
||||||
}
|
}
|
||||||
|
|
||||||
this._add_settings_keybinding('toggle-xr-effect-shortcut', this._toggle_xr_effect.bind(this));
|
|
||||||
this._add_settings_keybinding('recenter-display-shortcut', this._recenter_display.bind(this));
|
this._add_settings_keybinding('recenter-display-shortcut', this._recenter_display.bind(this));
|
||||||
this._add_settings_keybinding('toggle-display-distance-shortcut', this._virtual_displays_actor._change_distance.bind(this._virtual_displays_actor));
|
this._add_settings_keybinding('toggle-display-distance-shortcut', this._virtual_displays_actor._change_distance.bind(this._virtual_displays_actor));
|
||||||
this._add_settings_keybinding('toggle-follow-shortcut', this._toggle_follow_mode.bind(this));
|
this._add_settings_keybinding('toggle-follow-shortcut', this._toggle_follow_mode.bind(this));
|
||||||
|
|
@ -558,7 +559,6 @@ export default class BreezyDesktopExtension extends Extension {
|
||||||
|
|
||||||
if (Globals.data_stream.smooth_follow_enabled) this._toggle_follow_mode();
|
if (Globals.data_stream.smooth_follow_enabled) this._toggle_follow_mode();
|
||||||
|
|
||||||
Main.wm.removeKeybinding('toggle-xr-effect-shortcut');
|
|
||||||
Main.wm.removeKeybinding('recenter-display-shortcut');
|
Main.wm.removeKeybinding('recenter-display-shortcut');
|
||||||
Main.wm.removeKeybinding('toggle-display-distance-shortcut');
|
Main.wm.removeKeybinding('toggle-display-distance-shortcut');
|
||||||
Main.wm.removeKeybinding('toggle-follow-shortcut');
|
Main.wm.removeKeybinding('toggle-follow-shortcut');
|
||||||
|
|
@ -644,6 +644,7 @@ export default class BreezyDesktopExtension extends Extension {
|
||||||
Globals.data_stream.disconnect(this._breezy_desktop_running_connection);
|
Globals.data_stream.disconnect(this._breezy_desktop_running_connection);
|
||||||
this._breezy_desktop_running_connection = null;
|
this._breezy_desktop_running_connection = null;
|
||||||
}
|
}
|
||||||
|
Main.wm.removeKeybinding('toggle-xr-effect-shortcut');
|
||||||
Gio.Settings.unbind(this.settings, 'debug');
|
Gio.Settings.unbind(this.settings, 'debug');
|
||||||
Gio.Settings.unbind(this.settings, 'use-optimal-monitor-config');
|
Gio.Settings.unbind(this.settings, 'use-optimal-monitor-config');
|
||||||
Gio.Settings.unbind(this.settings, 'headset-as-primary');
|
Gio.Settings.unbind(this.settings, 'headset-as-primary');
|
||||||
|
|
|
||||||
|
|
@ -329,8 +329,9 @@ export const VirtualDisplayEffect = GObject.registerClass({
|
||||||
|
|
||||||
if (this._follow_ease_timeline?.is_playing()) this._follow_ease_timeline.stop();
|
if (this._follow_ease_timeline?.is_playing()) this._follow_ease_timeline.stop();
|
||||||
|
|
||||||
|
const ease_to_focus = this.smooth_follow_enabled && this._is_focused();
|
||||||
const from = this._current_follow_ease_progress;
|
const from = this._current_follow_ease_progress;
|
||||||
const to = this.smooth_follow_enabled && this._is_focused() ? 1.0 : 0.0;
|
const to = ease_to_focus ? 1.0 : 0.0;
|
||||||
const toggleTime = this.smooth_follow_toggle_epoch_ms === 0 ? Date.now() : this.smooth_follow_toggle_epoch_ms;
|
const toggleTime = this.smooth_follow_toggle_epoch_ms === 0 ? Date.now() : this.smooth_follow_toggle_epoch_ms;
|
||||||
|
|
||||||
// would have been a slight delay between request and slerp actually starting
|
// would have been a slight delay between request and slerp actually starting
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,34 @@ const FOCUS_THRESHOLD = 0.95 / 2.0;
|
||||||
// if we leave the monitor with some margin, unfocus even if no other monitor is in focus
|
// if we leave the monitor with some margin, unfocus even if no other monitor is in focus
|
||||||
const UNFOCUS_THRESHOLD = 1.1 / 2.0;
|
const UNFOCUS_THRESHOLD = 1.1 / 2.0;
|
||||||
|
|
||||||
|
// returns how far the look vector is from the center of the monitor, as a percentage of the monitor's width
|
||||||
|
function getMonitorDistance(fovDetails, lookUpPixels, lookWestPixels, monitorVector, monitorDetails, upAngleToLength, westAngleToLength) {
|
||||||
|
const monitorAspectRatio = monitorDetails.width / monitorDetails.height;
|
||||||
|
|
||||||
|
// weight the up distance by the aspect ratio
|
||||||
|
const vectorUpPixels = upAngleToLength(
|
||||||
|
fovDetails.defaultDistanceVerticalRadians,
|
||||||
|
fovDetails.heightPixels,
|
||||||
|
fovDetails.completeScreenDistancePixels,
|
||||||
|
monitorVector[2],
|
||||||
|
monitorVector[0]
|
||||||
|
);
|
||||||
|
const upDeltaPixels = (lookUpPixels - vectorUpPixels) * monitorAspectRatio;
|
||||||
|
|
||||||
|
const vectorWestPixels = westAngleToLength(
|
||||||
|
fovDetails.defaultDistanceHorizontalRadians,
|
||||||
|
fovDetails.widthPixels,
|
||||||
|
fovDetails.completeScreenDistancePixels,
|
||||||
|
monitorVector[1],
|
||||||
|
monitorVector[0]
|
||||||
|
);
|
||||||
|
const westDeltaPixels = lookWestPixels - vectorWestPixels;
|
||||||
|
const totalDeltaPixels = Math.sqrt(upDeltaPixels * upDeltaPixels + westDeltaPixels * westDeltaPixels);
|
||||||
|
|
||||||
|
// threshold is a percentage of width, and height was already properly weighted
|
||||||
|
return totalDeltaPixels / monitorDetails.width;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Find the vector in the array that's closest to the quaternion rotation
|
* Find the vector in the array that's closest to the quaternion rotation
|
||||||
*
|
*
|
||||||
|
|
@ -26,12 +54,11 @@ const UNFOCUS_THRESHOLD = 1.1 / 2.0;
|
||||||
* @param {number[][]} monitorVectors - Array of monitor vectors [x, y, z] to search from
|
* @param {number[][]} monitorVectors - Array of monitor vectors [x, y, z] to search from
|
||||||
* @param {number} currentFocusedIndex - Index of the currently focused monitor
|
* @param {number} currentFocusedIndex - Index of the currently focused monitor
|
||||||
* @param {number} focusedMonitorDistance - Distance to the focused monitor, < 1.0 if zoomed in
|
* @param {number} focusedMonitorDistance - Distance to the focused monitor, < 1.0 if zoomed in
|
||||||
* @param {boolean} smoothFollowEnabled - If true, always keep the current monitor in focus or choose the closest
|
|
||||||
* @param {Object} fovDetails - Contains reference widthPixels, heightPixels, horizontal and vertical radians, and pixel distance to the center of the screen
|
* @param {Object} fovDetails - Contains reference widthPixels, heightPixels, horizontal and vertical radians, and pixel distance to the center of the screen
|
||||||
* @param {Object[]} monitorsDetails - Contains x, y, width, height (coordinates from top-left) for each monitor
|
* @param {Object[]} monitorsDetails - Contains x, y, width, height (coordinates from top-left) for each monitor
|
||||||
* @returns {number} Index of the closest vector, if it surpasses the previous closest index by a certain margin, otherwise the previous index
|
* @returns {number} Index of the closest vector, if it surpasses the previous closest index by a certain margin, otherwise the previous index
|
||||||
*/
|
*/
|
||||||
function findFocusedMonitor(quaternion, monitorVectors, currentFocusedIndex, focusedMonitorDistance, smoothFollowEnabled, fovDetails, monitorsDetails) {
|
function findFocusedMonitor(quaternion, monitorVectors, currentFocusedIndex, focusedMonitorDistance, fovDetails, monitorsDetails) {
|
||||||
const lookVector = [1.0, 0.0, 0.0]; // NWU vector pointing to the center of the screen
|
const lookVector = [1.0, 0.0, 0.0]; // NWU vector pointing to the center of the screen
|
||||||
const rotatedLookVector = applyQuaternionToVector(lookVector, quaternion);
|
const rotatedLookVector = applyQuaternionToVector(lookVector, quaternion);
|
||||||
|
|
||||||
|
|
@ -56,55 +83,46 @@ function findFocusedMonitor(quaternion, monitorVectors, currentFocusedIndex, foc
|
||||||
|
|
||||||
let closestIndex = -1;
|
let closestIndex = -1;
|
||||||
let closestDistance = Infinity;
|
let closestDistance = Infinity;
|
||||||
let currentFocusedDistance = Infinity;
|
|
||||||
|
// the currently focused monitor is the most likely to be the closest, check it first and exit early if it is
|
||||||
|
if (currentFocusedIndex !== -1) {
|
||||||
|
const focusedDistance = getMonitorDistance(
|
||||||
|
fovDetails,
|
||||||
|
lookUpPixels,
|
||||||
|
lookWestPixels,
|
||||||
|
monitorVectors[currentFocusedIndex],
|
||||||
|
monitorsDetails[currentFocusedIndex],
|
||||||
|
upConversionFns.angleToLength,
|
||||||
|
westConversionFns.angleToLength
|
||||||
|
) * focusedMonitorDistance;
|
||||||
|
|
||||||
|
if (focusedDistance < UNFOCUS_THRESHOLD) return currentFocusedIndex;
|
||||||
|
}
|
||||||
|
|
||||||
// find the vector closest to the rotated look vector
|
// find the vector closest to the rotated look vector
|
||||||
monitorVectors.forEach((monitorVector, index) => {
|
monitorVectors.forEach((monitorVector, index) => {
|
||||||
const monitor = monitorsDetails[index];
|
if (index === currentFocusedIndex) return;
|
||||||
const monitorAspectRatio = monitor.width / monitor.height;
|
|
||||||
|
|
||||||
// weight the up distance by the aspect ratio
|
const distance = getMonitorDistance(
|
||||||
const vectorUpPixels = upConversionFns.angleToLength(
|
fovDetails,
|
||||||
fovDetails.defaultDistanceVerticalRadians,
|
lookUpPixels,
|
||||||
fovDetails.heightPixels,
|
lookWestPixels,
|
||||||
fovDetails.completeScreenDistancePixels,
|
monitorVector,
|
||||||
monitorVector[2],
|
monitorsDetails[index],
|
||||||
monitorVector[0]
|
upConversionFns.angleToLength,
|
||||||
|
westConversionFns.angleToLength
|
||||||
);
|
);
|
||||||
const upDeltaPixels = (lookUpPixels - vectorUpPixels) * monitorAspectRatio;
|
|
||||||
|
|
||||||
const vectorWestPixels = westConversionFns.angleToLength(
|
if (distance < closestDistance) {
|
||||||
fovDetails.defaultDistanceHorizontalRadians,
|
|
||||||
fovDetails.widthPixels,
|
|
||||||
fovDetails.completeScreenDistancePixels,
|
|
||||||
monitorVector[1],
|
|
||||||
monitorVector[0]
|
|
||||||
);
|
|
||||||
const westDeltaPixels = lookWestPixels - vectorWestPixels;
|
|
||||||
const totalDeltaPixels = Math.sqrt(upDeltaPixels * upDeltaPixels + westDeltaPixels * westDeltaPixels);
|
|
||||||
|
|
||||||
// threshold is a percentage of width, and height was already properly weighted
|
|
||||||
const distanceFromCenterSizeRatio = totalDeltaPixels / monitor.width;
|
|
||||||
|
|
||||||
if (currentFocusedIndex === index) {
|
|
||||||
currentFocusedDistance = distanceFromCenterSizeRatio * focusedMonitorDistance;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (distanceFromCenterSizeRatio < closestDistance) {
|
|
||||||
closestIndex = index;
|
closestIndex = index;
|
||||||
closestDistance = distanceFromCenterSizeRatio;
|
closestDistance = distance;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const keepCurrent = currentFocusedIndex !== -1 && (smoothFollowEnabled || currentFocusedDistance < UNFOCUS_THRESHOLD);
|
if (closestDistance < FOCUS_THRESHOLD) return closestIndex;
|
||||||
if (!keepCurrent) {
|
|
||||||
if (smoothFollowEnabled || closestDistance < FOCUS_THRESHOLD) return closestIndex;
|
|
||||||
|
|
||||||
// neither the current nor the closest will take focus, unfocus all displays
|
// neither the current nor the closest will take focus, unfocus all displays
|
||||||
return -1;
|
return -1;
|
||||||
}
|
|
||||||
|
|
||||||
return currentFocusedIndex;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/***
|
/***
|
||||||
|
|
@ -761,7 +779,9 @@ export const VirtualDisplaysActor = GObject.registerClass({
|
||||||
if (this.show_banner) {
|
if (this.show_banner) {
|
||||||
this.focused_monitor_index = -1;
|
this.focused_monitor_index = -1;
|
||||||
this.focused_monitor_details = null;
|
this.focused_monitor_details = null;
|
||||||
} else if (this.imu_snapshots && (!this._smooth_follow_slerping || this.focused_monitor_index === -1)) {
|
} else if (this.imu_snapshots &&
|
||||||
|
(!this.smooth_follow_enabled || this.focused_monitor_index === -1) &&
|
||||||
|
(!this._smooth_follow_slerping || this.focused_monitor_index === -1)) {
|
||||||
// if smooth follow is enabled, use the origin IMU data to inform the initial focused monitor
|
// if smooth follow is enabled, use the origin IMU data to inform the initial focused monitor
|
||||||
// since it reflects where the user is looking in relation to the original monitor positions
|
// since it reflects where the user is looking in relation to the original monitor positions
|
||||||
const currentPoseQuat = this.smooth_follow_enabled ?
|
const currentPoseQuat = this.smooth_follow_enabled ?
|
||||||
|
|
@ -773,7 +793,6 @@ export const VirtualDisplaysActor = GObject.registerClass({
|
||||||
this.monitor_placements.map(monitorVectors => monitorVectors.centerLook),
|
this.monitor_placements.map(monitorVectors => monitorVectors.centerLook),
|
||||||
this.focused_monitor_index,
|
this.focused_monitor_index,
|
||||||
this.display_distance / this._display_distance_default(),
|
this.display_distance / this._display_distance_default(),
|
||||||
this.smooth_follow_enabled,
|
|
||||||
this.fov_details,
|
this.fov_details,
|
||||||
this._all_monitors
|
this._all_monitors
|
||||||
);
|
);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue