diff options
Diffstat (limited to 'src/utilities')
-rw-r--r-- | src/utilities/animatedValue.vala | 13 | ||||
-rw-r--r-- | src/utilities/bindingManager.vala | 34 | ||||
-rw-r--r-- | src/utilities/config.vala | 5 | ||||
-rw-r--r-- | src/utilities/focusGrabber.vala | 99 | ||||
-rw-r--r-- | src/utilities/key.vala | 26 | ||||
-rw-r--r-- | src/utilities/paths.vala | 68 | ||||
-rw-r--r-- | src/utilities/trigger.vala | 36 |
7 files changed, 197 insertions, 84 deletions
diff --git a/src/utilities/animatedValue.vala b/src/utilities/animatedValue.vala index 32ab889..7acc7a7 100644 --- a/src/utilities/animatedValue.vala +++ b/src/utilities/animatedValue.vala @@ -116,10 +116,16 @@ public class AnimatedValue : GLib.Object { ///////////////////////////////////////////////////////////////////// public void reset_target(double end, double duration) { - this.start = this.val; this.end = end; this.duration = duration; - this.state = 0.0; + this.start = this.val; + + if (duration == 0.0) { + this.val = end; + this.state = 1.0; + } else { + this.state = 0.0; + } } ///////////////////////////////////////////////////////////////////// @@ -129,7 +135,7 @@ public class AnimatedValue : GLib.Object { public void update(double time) { this.state += time/this.duration; - if (state < 1) { + if (this.state < 1) { switch (this.type) { case Type.LINEAR: @@ -152,6 +158,7 @@ public class AnimatedValue : GLib.Object { } break; } + } else if (this.val != this.end) { this.val = this.end; } diff --git a/src/utilities/bindingManager.vala b/src/utilities/bindingManager.vala index 437f4c1..5a4548e 100644 --- a/src/utilities/bindingManager.vala +++ b/src/utilities/bindingManager.vala @@ -54,6 +54,12 @@ public class BindingManager : GLib.Object { Gdk.ModifierType.MOD2_MASK|Gdk.ModifierType.LOCK_MASK|Gdk.ModifierType.MOD5_MASK }; + ///////////////////////////////////////////////////////////////////// + /// Some variables to remember which delayed binding was delayed. + /// When the delay passes without another event indicating that the + /// Trigger was released, the stored binding will be activated. + ///////////////////////////////////////////////////////////////////// + private uint32 delayed_count = 0; private X.Event? delayed_event = null; private Keybinding? delayed_binding = null; @@ -91,9 +97,8 @@ public class BindingManager : GLib.Object { public void bind(Trigger trigger, string id) { if(trigger.key_code != 0) { - Gdk.Window rootwin = Gdk.get_default_root_window(); - X.Display display = Gdk.x11_drawable_get_xdisplay(rootwin); - X.ID xid = Gdk.x11_drawable_get_xid(rootwin); + X.Display display = Gdk.x11_get_default_xdisplay(); + X.ID xid = Gdk.x11_get_default_root_xwindow(); Gdk.error_trap_push(); @@ -121,9 +126,9 @@ public class BindingManager : GLib.Object { ///////////////////////////////////////////////////////////////////// public void unbind(string id) { - Gdk.Window rootwin = Gdk.get_default_root_window(); - X.Display display = Gdk.x11_drawable_get_xdisplay(rootwin); - X.ID xid = Gdk.x11_drawable_get_xid(rootwin); + X.Display display = Gdk.x11_get_default_xdisplay(); + X.ID xid = Gdk.x11_get_default_root_xwindow(); + Gee.List<Keybinding> remove_bindings = new Gee.ArrayList<Keybinding>(); foreach(var binding in bindings) { if(id == binding.id) { @@ -185,6 +190,20 @@ public class BindingManager : GLib.Object { } ///////////////////////////////////////////////////////////////////// + /// Returns whether the pie with the given ID opens centered. + ///////////////////////////////////////////////////////////////////// + + public bool get_is_centered(string id) { + foreach (var binding in bindings) { + if (binding.id == id) { + return binding.trigger.centered; + } + } + + return false; + } + + ///////////////////////////////////////////////////////////////////// /// Returns the name ID of the Pie bound to the given Trigger. /// Returns "" if there is nothing bound to this trigger. ///////////////////////////////////////////////////////////////////// @@ -258,8 +277,7 @@ public class BindingManager : GLib.Object { // if the trigger is released and an event is currently waiting // simulate that the trigger has been pressed without any inter- // ference of Gnome-Pie - Gdk.Window rootwin = Gdk.get_default_root_window(); - X.Display display = Gdk.x11_drawable_get_xdisplay(rootwin); + X.Display display = Gdk.x11_get_default_xdisplay(); // unbind the trigger, else we'll capture that event again ;) unbind(delayed_binding.id); diff --git a/src/utilities/config.vala b/src/utilities/config.vala index cf4311d..5790eef 100644 --- a/src/utilities/config.vala +++ b/src/utilities/config.vala @@ -55,7 +55,6 @@ public class Config : GLib.Object { public double refresh_rate { get; set; default = 60.0; } public double global_scale { get; set; default = 1.0; } public bool show_indicator { get; set; default = true; } - public bool open_at_mouse { get; set; default = true; } public bool auto_start { get; set; default = false; } public Gee.ArrayList<Theme?> themes { get; private set; } @@ -71,7 +70,6 @@ public class Config : GLib.Object { writer.write_attribute("refresh_rate", refresh_rate.to_string()); writer.write_attribute("global_scale", global_scale.to_string()); writer.write_attribute("show_indicator", show_indicator ? "true" : "false"); - writer.write_attribute("open_at_mouse", open_at_mouse ? "true" : "false"); writer.end_element(); writer.end_document(); } @@ -114,9 +112,6 @@ public class Config : GLib.Object { case "show_indicator": show_indicator = bool.parse(attr_content); break; - case "open_at_mouse": - open_at_mouse = bool.parse(attr_content); - break; default: warning("Invalid setting \"" + attr_name + "\" in gnome-pie.conf!"); break; diff --git a/src/utilities/focusGrabber.vala b/src/utilities/focusGrabber.vala index 0e07b39..293e103 100644 --- a/src/utilities/focusGrabber.vala +++ b/src/utilities/focusGrabber.vala @@ -25,48 +25,95 @@ public class FocusGrabber : GLib.Object { ///////////////////////////////////////////////////////////////////// /// Utilities for grabbing focus. - /// Code from Gnome-Do/Synapse. + /// Code roughly from Gnome-Do/Synapse. ///////////////////////////////////////////////////////////////////// - public static void grab(Gtk.Window window) { - window.present_with_time(Gdk.CURRENT_TIME); - window.get_window().raise(); - window.get_window().focus(Gdk.CURRENT_TIME); + 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); - int i = 0; - Timeout.add(100, () => { - if (++i >= 100) return false; - return !try_grab_window(window); - }); + 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 from Gnome-Do/Synapse. + /// Code roughly from Gnome-Do/Synapse. ///////////////////////////////////////////////////////////////////// - public static void ungrab(Gtk.Window window) { - Gdk.pointer_ungrab(Gdk.CURRENT_TIME); - Gdk.keyboard_ungrab(Gdk.CURRENT_TIME); - Gtk.grab_remove(window); + public static void ungrab(bool keyboard = true, bool pointer = true) { + #if HAVE_GTK_3 + + var display = Gdk.Display.get_default(); + var manager = display.get_device_manager(); + + unowned 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); + } + + #else + + if (pointer) Gdk.pointer_ungrab(Gdk.CURRENT_TIME); + if (keyboard) Gdk.keyboard_ungrab(Gdk.CURRENT_TIME); + + #endif } ///////////////////////////////////////////////////////////////////// - /// Code from Gnome-Do/Synapse. + /// Code roughly from Gnome-Do/Synapse. ///////////////////////////////////////////////////////////////////// - private static bool try_grab_window(Gtk.Window window) { - if (Gdk.pointer_grab(window.get_window(), true, Gdk.EventMask.BUTTON_PRESS_MASK | - Gdk.EventMask.BUTTON_RELEASE_MASK | Gdk.EventMask.POINTER_MOTION_MASK, - null, null, Gdk.CURRENT_TIME) == Gdk.GrabStatus.SUCCESS) { + private static bool try_grab_window(Gdk.Window window, bool keyboard, bool pointer, bool owner_events) { + #if HAVE_GTK_3 + + var display = Gdk.Display.get_default(); + var manager = display.get_device_manager(); - if (Gdk.keyboard_grab(window.get_window(), true, Gdk.CURRENT_TIME) == Gdk.GrabStatus.SUCCESS) { - Gtk.grab_add(window); + bool grabbed_all = true; + + unowned 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; - } else { - Gdk.pointer_ungrab(Gdk.CURRENT_TIME); - return false; + + ungrab(keyboard, pointer); + + #else + + if (!pointer || Gdk.pointer_grab(window, owner_events, Gdk.EventMask.BUTTON_PRESS_MASK | + Gdk.EventMask.BUTTON_RELEASE_MASK | Gdk.EventMask.POINTER_MOTION_MASK, + null, null, Gdk.CURRENT_TIME) == Gdk.GrabStatus.SUCCESS) { + + if (!keyboard || Gdk.keyboard_grab(window, owner_events, Gdk.CURRENT_TIME) == Gdk.GrabStatus.SUCCESS) { + return true; + } else if (pointer) { + ungrab(false, true); + return false; + } } - } + #endif + return false; } } diff --git a/src/utilities/key.vala b/src/utilities/key.vala index 6700b16..5f27a1e 100644 --- a/src/utilities/key.vala +++ b/src/utilities/key.vala @@ -55,10 +55,21 @@ public class Key : GLib.Object { private Gdk.ModifierType modifiers; ///////////////////////////////////////////////////////////////////// + /// C'tor, initializes all members to defaults. + ///////////////////////////////////////////////////////////////////// + + public Key() { + this.accelerator = ""; + this.modifiers = 0; + this.key_code = 0; + this.label = _("Not bound"); + } + + ///////////////////////////////////////////////////////////////////// /// C'tor, initializes all members. ///////////////////////////////////////////////////////////////////// - public Key(string stroke) { + public Key.from_string(string stroke) { this.accelerator = stroke; uint keysym; @@ -68,6 +79,17 @@ public class Key : GLib.Object { } ///////////////////////////////////////////////////////////////////// + /// C'tor, initializes all members. + ///////////////////////////////////////////////////////////////////// + + public Key.from_values(uint keysym, Gdk.ModifierType modifiers) { + this.accelerator = Gtk.accelerator_name(keysym, modifiers); + this.label = Gtk.accelerator_get_label(keysym, modifiers); + this.key_code = display.keysym_to_keycode(keysym); + this.modifiers = modifiers; + } + + ///////////////////////////////////////////////////////////////////// /// Initializes static members. ///////////////////////////////////////////////////////////////////// @@ -113,7 +135,7 @@ public class Key : GLib.Object { private Gdk.ModifierType get_modifiers() { Gdk.ModifierType modifiers; - Gdk.Display.get_default().get_pointer(null, null, null, out modifiers); + Gtk.get_current_event_state(out modifiers); return modifiers; } diff --git a/src/utilities/paths.vala b/src/utilities/paths.vala index 1c42176..589cc36 100644 --- a/src/utilities/paths.vala +++ b/src/utilities/paths.vala @@ -60,6 +60,13 @@ public class Paths : GLib.Object { public static string locales { get; private set; default=""; } ///////////////////////////////////////////////////////////////////// + /// The directory containing UI declaration files + /// usually /usr/share/gnome-pie/ui/. + ///////////////////////////////////////////////////////////////////// + + public static string ui_files { get; private set; default=""; } + + ///////////////////////////////////////////////////////////////////// /// The autostart file of gnome-pie_config /// usually ~/.config/autostart/gnome-pie.desktop. ///////////////////////////////////////////////////////////////////// @@ -74,43 +81,47 @@ public class Paths : GLib.Object { public static string launchers { get; private set; default=""; } ///////////////////////////////////////////////////////////////////// + /// The path to the executable. + ///////////////////////////////////////////////////////////////////// + + public static string executable { get; private set; default=""; } + + ///////////////////////////////////////////////////////////////////// /// Initializes all values above. ///////////////////////////////////////////////////////////////////// public static void init() { - // append resources to icon search path to icon theme, if neccasary + // get path of executable try { - var icon_dir = GLib.File.new_for_path(GLib.Path.get_dirname( - GLib.FileUtils.read_link("/proc/self/exe"))).get_child("resources"); - - if (icon_dir.query_exists()) { - string path = icon_dir.get_path(); - Gtk.IconTheme.get_default().append_search_path(path); - } - - Gtk.IconTheme.get_default().append_search_path("/usr/share/pixmaps/"); - + executable = GLib.File.new_for_path(GLib.FileUtils.read_link("/proc/self/exe")).get_path(); } catch (GLib.FileError e) { warning("Failed to get path of executable!"); } + // append resources to icon search path to icon theme, if neccasary + var icon_dir = GLib.File.new_for_path(GLib.Path.get_dirname(executable)).get_child("resources"); + + if (icon_dir.query_exists()) { + string path = icon_dir.get_path(); + Gtk.IconTheme.get_default().append_search_path(path); + } + + Gtk.IconTheme.get_default().append_search_path("/usr/share/pixmaps/"); + // get global paths var default_dir = GLib.File.new_for_path("/usr/share/gnome-pie/"); if(!default_dir.query_exists()) { default_dir = GLib.File.new_for_path("/usr/local/share/gnome-pie/"); if(!default_dir.query_exists()) { - try { - default_dir = GLib.File.new_for_path(GLib.Path.get_dirname( - GLib.FileUtils.read_link("/proc/self/exe"))).get_child("resources"); - } catch (GLib.FileError e) { - warning("Failed to get path of executable!"); - } + default_dir = GLib.File.new_for_path(GLib.Path.get_dirname( + executable)).get_child("resources"); } } global_themes = default_dir.get_path() + "/themes"; + ui_files = default_dir.get_path() + "/ui"; // get locales path var locale_dir = GLib.File.new_for_path("/usr/share/locale/de/LC_MESSAGES/gnomepie.mo"); @@ -121,22 +132,12 @@ public class Paths : GLib.Object { if(locale_dir.query_exists()) { locale_dir = GLib.File.new_for_path("/usr/local/share/locale"); } else { - - try { - locale_dir = GLib.File.new_for_path(GLib.Path.get_dirname( - GLib.FileUtils.read_link("/proc/self/exe"))).get_child( - "resources/locale/de/LC_MESSAGES/gnomepie.mo"); - } catch (GLib.FileError e) { - warning("Failed to get path of executable!"); - } + locale_dir = GLib.File.new_for_path(GLib.Path.get_dirname( + executable)).get_child("resources/locale/de/LC_MESSAGES/gnomepie.mo"); if(locale_dir.query_exists()) { - try { - locale_dir = GLib.File.new_for_path(GLib.Path.get_dirname( - GLib.FileUtils.read_link("/proc/self/exe"))).get_child("resources/locale"); - } catch (GLib.FileError e) { - warning("Failed to get path of executable!"); - } + locale_dir = GLib.File.new_for_path(GLib.Path.get_dirname( + executable)).get_child("resources/locale"); } } } @@ -204,7 +205,10 @@ public class Paths : GLib.Object { warning("Failed to find launchers directory!"); if (!GLib.File.new_for_path(global_themes).query_exists()) - warning("Failed to find global themes directory!"); + warning("Failed to find global themes directory!"); + + if (!GLib.File.new_for_path(ui_files).query_exists()) + warning("Failed to find UI files directory!"); } } diff --git a/src/utilities/trigger.vala b/src/utilities/trigger.vala index 1f6fcfe..4b6167b 100644 --- a/src/utilities/trigger.vala +++ b/src/utilities/trigger.vala @@ -81,6 +81,12 @@ public class Trigger : GLib.Object { public bool delayed { get; private set; default=false; } ///////////////////////////////////////////////////////////////////// + /// True if the pie opens in the middle of the screen. + ///////////////////////////////////////////////////////////////////// + + public bool centered { get; private set; default=false; } + + ///////////////////////////////////////////////////////////////////// /// C'tor, creates a new, "unbound" Trigger. ///////////////////////////////////////////////////////////////////// @@ -93,7 +99,7 @@ public class Trigger : GLib.Object { /// in this format: "[option(s)]<modifier(s)>button" where /// "<modifier>" is something like "<Alt>" or "<Control>", "button" /// something like "s", "F4" or "button0" and "[option]" is either - /// "[turbo]" or "["delayed"]". + /// "[turbo]", "[centered]" or "["delayed"]". ///////////////////////////////////////////////////////////////////// public Trigger.from_string(string trigger) { @@ -105,9 +111,12 @@ public class Trigger : GLib.Object { ///////////////////////////////////////////////////////////////////// public Trigger.from_values(uint key_sym, Gdk.ModifierType modifiers, - bool with_mouse, bool turbo, bool delayed ) { + bool with_mouse, bool turbo, bool delayed, + bool centered ) { - string trigger = (turbo ? "[turbo]" : "") + (delayed ? "[delayed]" : ""); + string trigger = (turbo ? "[turbo]" : "") + + (delayed ? "[delayed]" : "") + + (centered ? "[centered]" : ""); if (with_mouse) { trigger += Gtk.accelerator_name(0, modifiers) + "button%u".printf(key_sym); @@ -123,7 +132,7 @@ public class Trigger : GLib.Object { /// in this format: "[option(s)]<modifier(s)>button" where /// "<modifier>" is something like "<Alt>" or "<Control>", "button" /// something like "s", "F4" or "button0" and "[option]" is either - /// "[turbo]" or "["delayed"]". + /// "[turbo]", "[centered]" or "["delayed"]". ///////////////////////////////////////////////////////////////////// public void parse_string(string trigger) { @@ -135,10 +144,12 @@ public class Trigger : GLib.Object { this.turbo = check_string.contains("[turbo]"); this.delayed = check_string.contains("[delayed]"); + this.centered = check_string.contains("[centered]"); // remove optional arguments check_string = check_string.replace("[turbo]", ""); check_string = check_string.replace("[delayed]", ""); + check_string = check_string.replace("[centered]", ""); int button = this.get_mouse_button(check_string); if (button > 0) { @@ -177,12 +188,20 @@ public class Trigger : GLib.Object { this.label_with_specials = this.label; - if (this.turbo && this.delayed) - this.label_with_specials += ("\n<small><span weight='light'>" + _("Turbo") + " | " + _("Delayed") + "</span></small>"); + if (this.turbo && this.delayed && this.centered) + this.label_with_specials += (" <small><span weight='light'>[ " + _("Turbo") + " | " + _("Delayed") + " | " + _("Centered") + " ]</span></small>"); + else if (this.turbo && this.centered) + this.label_with_specials += (" <small><span weight='light'>[ " + _("Turbo") + " | " + _("Centered") + " ]</span></small>"); + else if (this.turbo && this.delayed) + this.label_with_specials += (" <small><span weight='light'>[ " + _("Turbo") + " | " + _("Delayed") + " ]</span></small>"); + else if (this.centered && this.delayed) + this.label_with_specials += (" <small><span weight='light'>[ " + _("Delayed") + " | " + _("Centered") + " ]</span></small>"); else if (this.turbo) - this.label_with_specials += ("\n<small><span weight='light'>" + _("Turbo") + "</span></small>"); + this.label_with_specials += (" <small><span weight='light'>[ " + _("Turbo") + " ]</span></small>"); else if (this.delayed) - this.label_with_specials += ("\n<small><span weight='light'>" + _("Delayed") + "</span></small>"); + this.label_with_specials += (" <small><span weight='light'>[ " + _("Delayed") + " ]</span></small>"); + else if (this.centered) + this.label_with_specials += (" <small><span weight='light'>[ " + _("Centered") + " ]</span></small>"); } else { this.set_unbound(); @@ -216,6 +235,7 @@ public class Trigger : GLib.Object { // remove optional arguments check_string = check_string.replace("[turbo]", ""); check_string = check_string.replace("[delayed]", ""); + check_string = check_string.replace("[centered]", ""); if (this.get_mouse_button(check_string) > 0) { // it seems to be a valid mouse-trigger so replace button part, |