diff options
Diffstat (limited to 'src/utilities/focusGrabber.vala')
-rw-r--r-- | src/utilities/focusGrabber.vala | 97 |
1 files changed, 97 insertions, 0 deletions
diff --git a/src/utilities/focusGrabber.vala b/src/utilities/focusGrabber.vala new file mode 100644 index 0000000..baa5fed --- /dev/null +++ b/src/utilities/focusGrabber.vala @@ -0,0 +1,97 @@ +///////////////////////////////////////////////////////////////////////// +// Copyright (c) 2011-2015 by Simon Schneegans +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or (at +// your option) any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +///////////////////////////////////////////////////////////////////////// + +namespace GnomePie { + +///////////////////////////////////////////////////////////////////////// +/// Some helper methods which focus the input on a given Gtk.Window. +///////////////////////////////////////////////////////////////////////// + +public class FocusGrabber : GLib.Object { + + ///////////////////////////////////////////////////////////////////// + /// Utilities for grabbing focus. + /// Code roughly from Gnome-Do/Synapse. + ///////////////////////////////////////////////////////////////////// + + public static void grab(Gdk.Window window, bool keyboard = true, bool pointer = true, bool owner_events = true) { + if (keyboard || pointer) { + window.raise(); + window.focus(Gdk.CURRENT_TIME); + + if (!try_grab_window(window, keyboard, pointer, owner_events)) { + int i = 0; + Timeout.add(100, () => { + if (++i >= 100) return false; + return !try_grab_window(window, keyboard, pointer, owner_events); + }); + } + } + } + + ///////////////////////////////////////////////////////////////////// + /// Code roughly from Gnome-Do/Synapse. + ///////////////////////////////////////////////////////////////////// + + public static void ungrab(bool keyboard = true, bool pointer = true) { + var display = Gdk.Display.get_default(); + var manager = display.get_device_manager(); + + GLib.List<weak Gdk.Device?> list = manager.list_devices(Gdk.DeviceType.MASTER); + + foreach(var device in list) { + if ((device.input_source == Gdk.InputSource.KEYBOARD && keyboard) + || (device.input_source != Gdk.InputSource.KEYBOARD && pointer)) + + device.ungrab(Gdk.CURRENT_TIME); + } + } + + ///////////////////////////////////////////////////////////////////// + /// Code roughly from Gnome-Do/Synapse. + ///////////////////////////////////////////////////////////////////// + + private static bool try_grab_window(Gdk.Window window, bool keyboard, bool pointer, bool owner_events) { + var display = Gdk.Display.get_default(); + var manager = display.get_device_manager(); + + bool grabbed_all = true; + + GLib.List<weak Gdk.Device?> list = manager.list_devices(Gdk.DeviceType.MASTER); + + foreach(var device in list) { + if ((device.input_source == Gdk.InputSource.KEYBOARD && keyboard) + || (device.input_source != Gdk.InputSource.KEYBOARD && pointer)) { + + var status = device.grab(window, Gdk.GrabOwnership.APPLICATION, owner_events, + Gdk.EventMask.ALL_EVENTS_MASK, null, Gdk.CURRENT_TIME); + + if (status != Gdk.GrabStatus.SUCCESS) + grabbed_all = false; + } + } + + if (grabbed_all) + return true; + + ungrab(keyboard, pointer); + + return false; + } +} + +} |