173 lines
6.1 KiB
Diff
173 lines
6.1 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 9393d04..0b11d24 100644
|
||
|
--- a/js/ui/layout.js
|
||
|
+++ b/js/ui/layout.js
|
||
|
@@ -951,22 +951,38 @@ var LayoutManager = GObject.registerClass({
|
||
|
return ws.get_work_area_for_monitor(monitorIndex);
|
||
|
}
|
||
|
|
||
|
+ _findIndexForRect(x, y, width, height) {
|
||
|
+ let rect = new Meta.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();
|
||
|
- let rect = new Meta.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) {
|
||
|
this._updateRegionIdle = Meta.later_add(Meta.LaterType.BEFORE_REDRAW,
|
||
|
diff --git a/js/ui/magnifier.js b/js/ui/magnifier.js
|
||
|
index f4012de..f8d235f 100644
|
||
|
--- a/js/ui/magnifier.js
|
||
|
+++ b/js/ui/magnifier.js
|
||
|
@@ -46,6 +46,8 @@ var MouseSpriteContent = GObject.registerClass({
|
||
|
}, class MouseSpriteContent extends GObject.Object {
|
||
|
_init() {
|
||
|
super._init();
|
||
|
+ this._scale = 1.0;
|
||
|
+ this._monitorScale = 1.0;
|
||
|
this._texture = null;
|
||
|
}
|
||
|
|
||
|
@@ -53,7 +55,10 @@ var 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) {
|
||
|
@@ -70,6 +75,29 @@ var 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;
|
||
|
}
|
||
|
@@ -84,7 +112,19 @@ var 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();
|
||
|
}
|
||
|
});
|
||
|
@@ -113,6 +153,8 @@ var Magnifier = 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);
|
||
|
});
|
||
|
@@ -120,6 +162,13 @@ var Magnifier = 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.
|
||
|
@@ -256,6 +305,8 @@ var Magnifier = class Magnifier extends Signals.EventEmitter {
|
||
|
this.xMouse = xMouse;
|
||
|
this.yMouse = yMouse;
|
||
|
|
||
|
+ this._updateContentScale();
|
||
|
+
|
||
|
let sysMouseOverAny = false;
|
||
|
this._zoomRegions.forEach(zoomRegion => {
|
||
|
if (zoomRegion.scrollToMousePos())
|