173 lines
6.0 KiB
Diff
173 lines
6.0 KiB
Diff
From: =?utf-8?b?Ik1hcmNvIFRyZXZpc2FuIChUcmV2acOxbyki?= <mail@3v1n0.net>
|
|
Date: Wed, 27 Mar 2019 16:14:39 +0100
|
|
Subject: magnifier: Scale the sprite to match the current monitor scaling
|
|
|
|
Compute the sprite texture scale (unfortunately using a workaround, based on
|
|
mutter cursor size preferences, tying to figure out the closest texture integer
|
|
scaling), and use this value to compute the scaling that should be applied to
|
|
the sprite in order to match the current monitor scaling.
|
|
|
|
Origin: https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/475
|
|
Applied-Upstream: no
|
|
Forwarded: yes
|
|
---
|
|
js/ui/layout.js | 24 ++++++++++++++++++++----
|
|
js/ui/magnifier.js | 55 ++++++++++++++++++++++++++++++++++++++++++++++++++++--
|
|
2 files changed, 73 insertions(+), 6 deletions(-)
|
|
|
|
diff --git a/js/ui/layout.js b/js/ui/layout.js
|
|
index 3ba9b96..4d5cd5a 100644
|
|
--- a/js/ui/layout.js
|
|
+++ b/js/ui/layout.js
|
|
@@ -981,22 +981,38 @@ export const LayoutManager = GObject.registerClass({
|
|
return ws.get_work_area_for_monitor(monitorIndex);
|
|
}
|
|
|
|
+ _findIndexForRect(x, y, width, height) {
|
|
+ const rect = new Mtk.Rectangle({
|
|
+ x: Math.floor(x),
|
|
+ y: Math.floor(y),
|
|
+ width: Math.ceil(x + width) - Math.floor(x),
|
|
+ height: Math.ceil(y + height) - Math.floor(y),
|
|
+ });
|
|
+ return global.display.get_monitor_index_for_rect(rect);
|
|
+ }
|
|
+
|
|
// This call guarantees that we return some monitor to simplify usage of it
|
|
// In practice all tracked actors should be visible on some monitor anyway
|
|
findIndexForActor(actor) {
|
|
let [x, y] = actor.get_transformed_position();
|
|
let [w, h] = actor.get_transformed_size();
|
|
- const rect = new Mtk.Rectangle({x, y, width: w, height: h});
|
|
- return global.display.get_monitor_index_for_rect(rect);
|
|
+ return this._findIndexForRect(x, y, w, h);
|
|
}
|
|
|
|
- findMonitorForActor(actor) {
|
|
- let index = this.findIndexForActor(actor);
|
|
+ _findMonitorForIndex(index) {
|
|
if (index >= 0 && index < this.monitors.length)
|
|
return this.monitors[index];
|
|
return null;
|
|
}
|
|
|
|
+ findMonitorForActor(actor) {
|
|
+ return this._findMonitorForIndex(this.findIndexForActor(actor));
|
|
+ }
|
|
+
|
|
+ findMonitorForPoint(x, y) {
|
|
+ return this._findMonitorForIndex(this._findIndexForRect(x, y, 1, 1));
|
|
+ }
|
|
+
|
|
_queueUpdateRegions() {
|
|
if (!this._updateRegionIdle) {
|
|
const laters = global.compositor.get_laters();
|
|
diff --git a/js/ui/magnifier.js b/js/ui/magnifier.js
|
|
index ab8150b..13da38f 100644
|
|
--- a/js/ui/magnifier.js
|
|
+++ b/js/ui/magnifier.js
|
|
@@ -51,6 +51,8 @@ const MouseSpriteContent = GObject.registerClass({
|
|
}, class MouseSpriteContent extends GObject.Object {
|
|
_init() {
|
|
super._init();
|
|
+ this._scale = 1.0;
|
|
+ this._monitorScale = 1.0;
|
|
this._texture = null;
|
|
}
|
|
|
|
@@ -58,7 +60,10 @@ const MouseSpriteContent = GObject.registerClass({
|
|
if (!this._texture)
|
|
return [false, 0, 0];
|
|
|
|
- return [true, this._texture.get_width(), this._texture.get_height()];
|
|
+ let width = this._texture.get_width() / this._scale;
|
|
+ let height = this._texture.get_height() / this._scale;
|
|
+
|
|
+ return [true, width, height];
|
|
}
|
|
|
|
vfunc_paint_content(actor, node, _paintContext) {
|
|
@@ -75,6 +80,29 @@ const MouseSpriteContent = GObject.registerClass({
|
|
textureNode.add_rectangle(actor.get_content_box());
|
|
}
|
|
|
|
+ _textureScale() {
|
|
+ if (!this._texture)
|
|
+ return 1;
|
|
+
|
|
+ /* This is a workaround to guess the sprite scale; while it works file
|
|
+ * in normal scenarios, it's not guaranteed to work in all the cases,
|
|
+ * and so we should actually add an API to mutter that will allow us
|
|
+ * to know the real spirte texture scaling in order to adapt it to the
|
|
+ * wanted one. */
|
|
+ let avgSize = (this._texture.get_width() + this._texture.get_height()) / 2;
|
|
+ return Math.max(1, Math.floor(avgSize / Meta.prefs_get_cursor_size() + .1));
|
|
+ }
|
|
+
|
|
+ _recomputeScale() {
|
|
+ let scale = this._textureScale() / this._monitorScale;
|
|
+
|
|
+ if (this._scale !== scale) {
|
|
+ this._scale = scale;
|
|
+ return true;
|
|
+ }
|
|
+ return false;
|
|
+ }
|
|
+
|
|
get texture() {
|
|
return this._texture;
|
|
}
|
|
@@ -89,7 +117,19 @@ const MouseSpriteContent = GObject.registerClass({
|
|
|
|
if (!oldTexture || !coglTexture ||
|
|
oldTexture.get_width() !== coglTexture.get_width() ||
|
|
- oldTexture.get_height() !== coglTexture.get_height())
|
|
+ oldTexture.get_height() !== coglTexture.get_height()) {
|
|
+ this._recomputeScale();
|
|
+ this.invalidate_size();
|
|
+ }
|
|
+ }
|
|
+
|
|
+ get scale() {
|
|
+ return this._scale;
|
|
+ }
|
|
+
|
|
+ set monitorScale(monitorScale) {
|
|
+ this._monitorScale = monitorScale;
|
|
+ if (this._recomputeScale())
|
|
this.invalidate_size();
|
|
}
|
|
});
|
|
@@ -121,6 +161,8 @@ export class Magnifier extends Signals.EventEmitter {
|
|
this._settingsInit(aZoomRegion);
|
|
aZoomRegion.scrollContentsTo(this.xMouse, this.yMouse);
|
|
|
|
+ this._updateContentScale();
|
|
+
|
|
St.Settings.get().connect('notify::magnifier-active', () => {
|
|
this.setActive(St.Settings.get().magnifier_active);
|
|
});
|
|
@@ -128,6 +170,13 @@ export class Magnifier extends Signals.EventEmitter {
|
|
this.setActive(St.Settings.get().magnifier_active);
|
|
}
|
|
|
|
+ _updateContentScale() {
|
|
+ let monitor = Main.layoutManager.findMonitorForPoint(this.xMouse,
|
|
+ this.yMouse);
|
|
+ this._mouseSprite.content.monitorScale = monitor
|
|
+ ? monitor.geometry_scale : 1;
|
|
+ }
|
|
+
|
|
/**
|
|
* showSystemCursor:
|
|
* Show the system mouse pointer.
|
|
@@ -269,6 +318,8 @@ export class Magnifier extends Signals.EventEmitter {
|
|
this.xMouse = xMouse;
|
|
this.yMouse = yMouse;
|
|
|
|
+ this._updateContentScale();
|
|
+
|
|
let sysMouseOverAny = false;
|
|
this._zoomRegions.forEach(zoomRegion => {
|
|
if (zoomRegion.scrollToMousePos())
|