aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Gabriel <mike.gabriel@das-netzwerkteam.de>2024-04-08 12:20:36 +0200
committerMike Gabriel <mike.gabriel@das-netzwerkteam.de>2024-04-08 12:20:36 +0200
commit0a20bb249db592bf43224a1ef7e9779ee26b1f29 (patch)
tree6cf62d73752a155610f498043320f3b6e7445abf
parente09ca756476c0aa594890bcb1cc52228073649e0 (diff)
parentf9a1300290a032e8f892774c2db3e4c79c758679 (diff)
downloadarctica-greeter-0a20bb249db592bf43224a1ef7e9779ee26b1f29.tar.gz
arctica-greeter-0a20bb249db592bf43224a1ef7e9779ee26b1f29.tar.bz2
arctica-greeter-0a20bb249db592bf43224a1ef7e9779ee26b1f29.zip
Merge branch 'tari01-pr/magnifier-focus'
Attributest GH PR #103: https://github.com/ArcticaProject/arctica-greeter/pull/103
-rw-r--r--Makefile.am3
-rwxr-xr-xarctica-greeter-magnifier107
-rwxr-xr-x[-rw-r--r--]src/arctica-greeter.vala110
3 files changed, 184 insertions, 36 deletions
diff --git a/Makefile.am b/Makefile.am
index 112eb3e..16dc40c 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -12,7 +12,8 @@ pkglibexec_SCRIPTS = lightdm-arctica-greeter-session \
arctica-greeter-guest-session-setup.sh \
arctica-greeter-check-hidpi \
arctica-greeter-enable-tap-to-click \
- arctica-greeter-set-keyboard-layout
+ arctica-greeter-set-keyboard-layout \
+ arctica-greeter-magnifier
EXTRA_DIST = \
autogen.sh \
diff --git a/arctica-greeter-magnifier b/arctica-greeter-magnifier
new file mode 100755
index 0000000..c4e5180
--- /dev/null
+++ b/arctica-greeter-magnifier
@@ -0,0 +1,107 @@
+#!/usr/bin/env python3
+
+import setproctitle
+import sys
+from functools import lru_cache
+import gi
+gi.require_version('Gtk', '3.0')
+from gi.repository import Gtk, Gdk, GLib, GdkPixbuf, Gio
+
+class Main(object):
+
+ def __init__(self):
+
+ self.window_x = 0
+ self.window_y = 0
+ self.w = Gtk.Window.new(Gtk.WindowType.TOPLEVEL)
+ self.w.set_size_request(300, 300)
+ self.w.set_title("Magnus")
+ self.w.connect("destroy", lambda a: Gtk.main_quit())
+ self.w.connect("configure-event", self.window_configure)
+ self.img = Gtk.Image()
+ scrolled_window = Gtk.ScrolledWindow()
+ scrolled_window.add(self.img)
+ self.w.add(scrolled_window)
+ self.w.show_all()
+ sys.stdout.write('%d\n' % self.w.get_window().get_xid())
+ sys.stdout.flush()
+ GLib.timeout_add(250, self.poll)
+ Gtk.main()
+
+ def poll(self, *args):
+
+ loc = self.w.get_size()
+ width = loc.width
+ height = loc.height
+ (screen, x, y) = Gdk.Display.get_default().get_default_seat().get_pointer().get_position()
+
+ if (x > self.window_x and x <= (self.window_x + width + 0) and y > self.window_y and y <= (self.window_y + height + 0)):
+
+ white = self.get_white_pixbuf(width, height)
+ self.img.set_from_pixbuf(white)
+
+ else:
+
+ root = Gdk.get_default_root_window()
+ scaled_width = width // 2
+ scaled_height = height // 2
+ scaled_xoff = scaled_width // 2
+ scaled_yoff = scaled_height // 2
+ screenshot = Gdk.pixbuf_get_from_window(root, x - scaled_xoff, y - scaled_yoff, scaled_width, scaled_height)
+ scaled_pb = screenshot.scale_simple(width, height, GdkPixbuf.InterpType.NEAREST)
+ self.img.set_from_pixbuf(scaled_pb)
+
+ return True
+
+ @lru_cache()
+ def makesquares(self, overall_width, overall_height, square_size, value_on, value_off):
+
+ on_sq = list(value_on) * square_size
+ off_sq = list(value_off) * square_size
+ on_row = []
+ off_row = []
+
+ while len(on_row) < overall_width * len(value_on):
+
+ on_row += on_sq
+ on_row += off_sq
+ off_row += off_sq
+ off_row += on_sq
+
+ on_row = on_row[:overall_width * len(value_on)]
+ off_row = off_row[:overall_width * len(value_on)]
+ on_sq_row = on_row * square_size
+ off_sq_row = off_row * square_size
+ overall = []
+ count = 0
+
+ while len(overall) < overall_width * overall_height * len(value_on):
+
+ overall += on_sq_row
+ overall += off_sq_row
+ count += 2
+
+ overall = overall[:overall_width * overall_height * len(value_on)]
+
+ return overall
+
+ @lru_cache()
+ def get_white_pixbuf(self, width, height):
+
+ square_size = 16
+ light = (153, 153, 153, 255)
+ dark = (102, 102, 102, 255)
+ whole = self.makesquares(width, height, square_size, light, dark)
+ arr = GLib.Bytes.new(whole)
+
+ return GdkPixbuf.Pixbuf.new_from_bytes(arr, GdkPixbuf.Colorspace.RGB, True, 8, width, height, width * len(light))
+
+ def window_configure(self, window, ev):
+
+ self.window_x = ev.x
+ self.window_y = ev.y
+
+if __name__ == "__main__":
+
+ setproctitle.setproctitle('magnus')
+ Main()
diff --git a/src/arctica-greeter.vala b/src/arctica-greeter.vala
index 7e7fd47..a2aa59e 100644..100755
--- a/src/arctica-greeter.vala
+++ b/src/arctica-greeter.vala
@@ -2,7 +2,7 @@
*
* Copyright (C) 2011 Canonical Ltd
* Copyright (C) 2015-2017 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>
- * Copyright (C) 2023 Robert Tari
+ * Copyright (C) 2023-2024 Robert Tari
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 3 as
@@ -32,13 +32,13 @@ public class ArcticaGreeter : Object
public signal void starting_session ();
public MainWindow main_window { get; private set; default = null; }
public Gtk.Window? pKeyboardWindow { get; set; default = null; }
+ public Gtk.Window? pMagnifierWindow { get; set; default = null; }
public bool test_mode { get; construct; default = false; }
public bool test_highcontrast { get; construct; default = false; }
private string state_file;
private KeyFile state;
private DBusServer pServer;
private Cairo.XlibSurface background_surface;
-
private SettingsDaemon settings_daemon;
public bool orca_needs_kick;
@@ -57,7 +57,6 @@ public class ArcticaGreeter : Object
construct
{
Bus.own_name (BusType.SESSION, "org.ayatana.greeter", BusNameOwnerFlags.NONE, onBusAcquired);
-
greeter = new LightDM.Greeter ();
greeter.show_message.connect ((text, type) => { show_message (text, type); });
@@ -667,13 +666,28 @@ public class ArcticaGreeter : Object
keyboard_xid = pWindow.get_xid ();
}
- if (xwin != keyboard_xid && win.get_type_hint() != Gdk.WindowTypeHint.NOTIFICATION)
+ // Now check to see if this is the magnifier - no focus for it, either
+ X.Window nMagnifier = 0;
+
+ if (this.pMagnifierWindow != null)
+ {
+ Gdk.X11.Window pWindow = (Gdk.X11.Window) this.pMagnifierWindow.get_window ();
+ nMagnifier = pWindow.get_xid ();
+ }
+
+ if (xwin != keyboard_xid && xwin != nMagnifier && win.get_type_hint() != Gdk.WindowTypeHint.NOTIFICATION)
{
win.focus (Gdk.CURRENT_TIME);
/* Make sure to keep keyboard above */
if (this.pKeyboardWindow != null)
this.pKeyboardWindow.get_window ().raise ();
+
+ // And the magnifier on top of everything
+ if (this.pMagnifierWindow != null)
+ {
+ this.pMagnifierWindow.get_window ().raise ();
+ }
}
}
}
@@ -698,6 +712,12 @@ public class ArcticaGreeter : Object
/* Make sure to keep keyboard above */
if (this.pKeyboardWindow != null)
this.pKeyboardWindow.get_window ().raise ();
+
+ // And the magnifier on top of everything
+ if (this.pMagnifierWindow != null)
+ {
+ this.pMagnifierWindow.get_window ().raise ();
+ }
}
}
return Gdk.FilterReturn.CONTINUE;
@@ -1439,23 +1459,10 @@ public class DBusServer : Object
private Pid nOrca = 0;
private Pid nOnBoard = 0;
private Pid nMagnifier = 0;
- private Gtk.Socket pSocket = null;
+ private Gtk.Socket pKeyboardSocket = null;
+ private Gtk.Socket pMagnifierSocket = null;
private bool high_contrast_osk = AGSettings.get_boolean(AGSettings.KEY_HIGH_CONTRAST);
- private void onMagnifierClosed (Pid nPid, int nStatus)
- {
- nMagnifier = 0;
-
- try
- {
- this.pConnection.emit_signal (null, "/org/ayatana/greeter", "org.ayatana.greeter", "MagnifierClosed", null);
- }
- catch (Error pError)
- {
- error ("Panic: Could not send magnifier closed signal: %s", pError.message);
- }
- }
-
private void closePid (ref Pid nPid, int nMultiplier)
{
if (nPid > 0)
@@ -1554,11 +1561,11 @@ public class DBusServer : Object
closePid (ref nOnBoard, -1);
/* Sending SIGTERM to the plug (i.e. the onboard process group)
- * will destroy pSocket, so NULLing it now.
+ * will destroy pKeyboardSocket, so NULLing it now.
*/
debug ("Tearing down OSK's Gtk.Socket");
- this.pGreeter.pKeyboardWindow.remove (pSocket);
- pSocket = null;
+ this.pGreeter.pKeyboardWindow.remove (pKeyboardSocket);
+ pKeyboardSocket = null;
/* Start with fresh Gkt.Window object for OSK relaunch.
*/
@@ -1635,14 +1642,14 @@ public class DBusServer : Object
}
}
- if (pSocket == null)
+ if (pKeyboardSocket == null)
{
debug ("Creating Gtk.Socket for OSK");
- pSocket = new Gtk.Socket ();
- pSocket.show ();
+ pKeyboardSocket = new Gtk.Socket ();
+ pKeyboardSocket.show ();
}
- if ((this.pGreeter.pKeyboardWindow == null) && (pSocket != null))
+ if ((this.pGreeter.pKeyboardWindow == null) && (pKeyboardSocket != null))
{
debug ("Creating Gtk.Window for OSK");
this.pGreeter.pKeyboardWindow = new Gtk.Window ();
@@ -1651,14 +1658,14 @@ public class DBusServer : Object
this.pGreeter.pKeyboardWindow.set_title("OSK (theme: %s)".printf(sTheme));
}
- if ((this.pGreeter.pKeyboardWindow != null) && (pSocket != null) && (nId != 0))
+ if ((this.pGreeter.pKeyboardWindow != null) && (pKeyboardSocket != null) && (nId != 0))
{
/* attach the GtkSocket, which will host the onboard keyboard, to pKeyboardWindow */
debug ("Adding OSK Gtk.Socket to OSK Gtk.Window");
- this.pGreeter.pKeyboardWindow.add (pSocket);
+ this.pGreeter.pKeyboardWindow.add (pKeyboardSocket);
debug ("Attaching new onboard process to OSK Gtk.Socket (+ Gtk.Window)");
- pSocket.add_id (nId);
+ pKeyboardSocket.add_id (nId);
/* resize the keyboard window to cover the lower part of the screen */
debug ("Resizing OSK window.");
@@ -1733,24 +1740,57 @@ public class DBusServer : Object
public void ToggleMagnifier (bool bActive) throws GLib.DBusError, GLib.IOError
{
+ int nId = 0;
AGSettings.set_boolean (AGSettings.KEY_MAGNIFIER, bActive);
- if (bActive)
+ if (this.nMagnifier == 0)
{
try
{
- Process.spawn_async (null, {"magnus"}, null, SpawnFlags.SEARCH_PATH | SpawnFlags.DO_NOT_REAP_CHILD, null, out nMagnifier);
- GLib.ChildWatch.add (nMagnifier, onMagnifierClosed);
+ int nMagnifierFD = 0;
+ string sPath = Path.build_filename (Config.PKGLIBEXECDIR, "arctica-greeter-magnifier");
+ Process.spawn_async_with_pipes (null, {sPath}, null, SpawnFlags.SEARCH_PATH, null, out this.nMagnifier, null, out nMagnifierFD, null);
+ var pFile = FileStream.fdopen (nMagnifierFD, "r");
+ var sText = new char[1024];
+
+ if (pFile.gets (sText) != null)
+ {
+ nId = int.parse ((string) sText);
+ }
}
catch (Error pError)
{
warning ("Failed to run magnifier: %s", pError.message);
+
+ return;
}
}
- else
+
+ if (pMagnifierSocket == null)
+ {
+ debug ("Creating Gtk.Socket for the magnifier");
+ pMagnifierSocket = new Gtk.Socket ();
+ pMagnifierSocket.show ();
+ }
+
+ if ((this.pGreeter.pMagnifierWindow == null) && (pMagnifierSocket != null))
{
- closePid (ref nMagnifier, 1);
- nMagnifier = 0;
+ debug ("Creating Gtk.Window for the magnifier");
+ this.pGreeter.pMagnifierWindow = new Gtk.Window ();
+ this.pGreeter.pMagnifierWindow.accept_focus = false;
+ this.pGreeter.pMagnifierWindow.focus_on_map = false;
+ this.pGreeter.pMagnifierWindow.set_title ("Magnifier");
}
+
+ if ((this.pGreeter.pMagnifierWindow != null) && (pMagnifierSocket != null) && (nId != 0))
+ {
+ debug ("Adding the magnifier Gtk.Socket to the magnifier Gtk.Window");
+ this.pGreeter.pMagnifierWindow.add (pMagnifierSocket);
+
+ debug ("Attaching new magnifier process to the magnifier Gtk.Socket (+ Gtk.Window)");
+ pMagnifierSocket.add_id (nId);
+ }
+
+ this.pGreeter.pMagnifierWindow.visible = bActive;
}
}