diff options
Diffstat (limited to 'src')
65 files changed, 582 insertions, 549 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 4d1194f..fcbe1e9 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -5,17 +5,6 @@ # determine source and header files file(GLOB VALA_SRC RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.vala */*.vala) -if (${INDICATOR_FOUND}) - LIST(APPEND DEFINES --define HAVE_APPINDICATOR) -endif(${INDICATOR_FOUND}) -if (${INDICATOR3_FOUND}) - LIST(APPEND DEFINES --define HAVE_APPINDICATOR) -endif(${INDICATOR3_FOUND}) - -if (${GMENU3_FOUND}) - LIST(APPEND DEFINES --define HAVE_GMENU_3) -endif (${GMENU3_FOUND}) - # use valac to compile sources to c files vala_precompile( VALA_C @@ -24,7 +13,7 @@ vala_precompile( ${VALA_PKGS} OPTIONS --thread - ${DEFINES} + ${VALA_DEFINES} ) # compile c-sources diff --git a/src/actionGroups/actionGroup.vala b/src/actionGroups/actionGroup.vala index 3bc7086..cb3f125 100644 --- a/src/actionGroups/actionGroup.vala +++ b/src/actionGroups/actionGroup.vala @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// Copyright (c) 2011-2016 by Simon Schneegans +// Copyright (c) 2011-2017 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 diff --git a/src/actionGroups/bookmarkGroup.vala b/src/actionGroups/bookmarkGroup.vala index 3a36be6..dc859fa 100644 --- a/src/actionGroups/bookmarkGroup.vala +++ b/src/actionGroups/bookmarkGroup.vala @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// Copyright (c) 2011-2016 by Simon Schneegans +// Copyright (c) 2011-2017 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 @@ -41,12 +41,10 @@ public class BookmarkGroup : ActionGroup { } ///////////////////////////////////////////////////////////////////// - /// Two members needed to avoid useless, frequent changes of the - /// stored Actions. + /// Used to track changes in the bookmarks file. ///////////////////////////////////////////////////////////////////// - private bool changing = false; - private bool changed_again = false; + private GLib.FileMonitor monitor = null; ///////////////////////////////////////////////////////////////////// /// C'tor, initializes all members. @@ -65,14 +63,19 @@ public class BookmarkGroup : ActionGroup { construct { this.load(); - // add monitor - var bookmark_file = GLib.File.new_for_path( - GLib.Environment.get_home_dir()).get_child(".gtk-bookmarks"); + var bookmarks_file = get_bookmarks_file(); - if (bookmark_file.query_exists()) { + // add monitor + if (bookmarks_file != null) { try { - var monitor = bookmark_file.monitor(GLib.FileMonitorFlags.NONE); - monitor.changed.connect(this.reload); + this.monitor = bookmarks_file.monitor(GLib.FileMonitorFlags.NONE); + this.monitor.set_rate_limit(500); + this.monitor.changed.connect((file, other, type) => { + if(type == GLib.FileMonitorEvent.CHANGES_DONE_HINT) { + this.delete_all(); + this.load(); + } + }); } catch (GLib.Error e) { warning(e.message); } @@ -80,6 +83,24 @@ public class BookmarkGroup : ActionGroup { } ///////////////////////////////////////////////////////////////////// + /// Returns either ~/.gtk-bookmarks or ~/.config/gtk-3.0/bookmarks + ///////////////////////////////////////////////////////////////////// + + private GLib.File? get_bookmarks_file() { + var bookmarks_file = GLib.File.new_for_path( + GLib.Environment.get_home_dir()).get_child(".gtk-bookmarks"); + + if (bookmarks_file.query_exists()) return bookmarks_file; + + bookmarks_file = GLib.File.new_for_path( + GLib.Environment.get_home_dir()).get_child(".config/gtk-3.0/bookmarks"); + + if (bookmarks_file.query_exists()) return bookmarks_file; + + return null; + } + + ///////////////////////////////////////////////////////////////////// /// Adds Actions for each gtk-bookmark of the user and for his home /// folder, desktop and trash. ///////////////////////////////////////////////////////////////////// @@ -88,23 +109,27 @@ public class BookmarkGroup : ActionGroup { // add home folder this.add_action(ActionRegistry.new_for_uri("file://" + GLib.Environment.get_home_dir())); - // add .gtk-bookmarks - var bookmark_file = GLib.File.new_for_path( - GLib.Environment.get_home_dir()).get_child(".gtk-bookmarks"); + // add bookmarks + var bookmarks_file = get_bookmarks_file(); - if (!bookmark_file.query_exists()) { - warning("Failed to find file \".gtk-bookmarks\"!"); + if (bookmarks_file == null) { + warning("Failed to find bookmarks file!"); return; } try { - var dis = new DataInputStream(bookmark_file.read()); + var dis = new DataInputStream(bookmarks_file.read()); string line; while ((line = dis.read_line(null)) != null) { - var parts = line.split(" "); - string uri = parts[0]; - string name = parts[1]; + string uri = line; + string name = null; + + int first_space = line.index_of(" "); + if (first_space > 0) { + uri = line.slice(0, first_space); + name = line.slice(first_space+1, line.length); + } this.add_action(ActionRegistry.new_for_uri(uri, name)); } @@ -118,34 +143,6 @@ public class BookmarkGroup : ActionGroup { // add desktop this.add_action(ActionRegistry.new_for_uri("file://" + GLib.Environment.get_user_special_dir(GLib.UserDirectory.DESKTOP))); } - - ///////////////////////////////////////////////////////////////////// - /// Reloads all Bookmarks. Is called when the user's gtk-bookmarks - /// file changes. - ///////////////////////////////////////////////////////////////////// - - private void reload() { - // avoid too frequent changes... - if (!this.changing) { - this.changing = true; - Timeout.add(200, () => { - if (this.changed_again) { - this.changed_again = false; - return true; - } - - // reload - message("Bookmarks changed..."); - this.delete_all(); - this.load(); - - this.changing = false; - return false; - }); - } else { - this.changed_again = true; - } - } } } diff --git a/src/actionGroups/clipboardGroup.vala b/src/actionGroups/clipboardGroup.vala index 51c3d1a..63bb093 100644 --- a/src/actionGroups/clipboardGroup.vala +++ b/src/actionGroups/clipboardGroup.vala @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// Copyright (c) 2011-2016 by Simon Schneegans +// Copyright (c) 2011-2017 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 @@ -53,7 +53,7 @@ public class ClipboardGroup : ActionGroup { if (file.query_exists()) { try { var info = file.query_info("standard::icon", 0); - this.icon = Icon.get_icon_name(info.get_icon()); + this.icon = info.get_icon().to_string(); } catch (Error e) { warning("Failed to generate icon for ClipboardGroupItem."); } diff --git a/src/actionGroups/devicesGroup.vala b/src/actionGroups/devicesGroup.vala index 1ea8607..a9164f5 100644 --- a/src/actionGroups/devicesGroup.vala +++ b/src/actionGroups/devicesGroup.vala @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// Copyright (c) 2011-2016 by Simon Schneegans +// Copyright (c) 2011-2017 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 @@ -89,7 +89,8 @@ public class DevicesGroup : ActionGroup { // get icon var icon = mount.get_icon(); - this.add_action(new UriAction(mount.get_name(), Icon.get_icon_name(icon), mount.get_root().get_uri())); + this.add_action(new UriAction(mount.get_name(), + icon.to_string(), mount.get_root().get_uri())); } } diff --git a/src/actionGroups/groupRegistry.vala b/src/actionGroups/groupRegistry.vala index 89cde6a..eaaab24 100644 --- a/src/actionGroups/groupRegistry.vala +++ b/src/actionGroups/groupRegistry.vala @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// Copyright (c) 2011-2016 by Simon Schneegans +// Copyright (c) 2011-2017 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 @@ -54,28 +54,40 @@ public class GroupRegistry : GLib.Object { TypeDescription type_description; type_description = BookmarkGroup.register(); - types.add(typeof(BookmarkGroup).name()); - descriptions.set(typeof(BookmarkGroup).name(), type_description); + if (type_description != null) { + types.add(typeof(BookmarkGroup).name()); + descriptions.set(typeof(BookmarkGroup).name(), type_description); + } type_description = ClipboardGroup.register(); - types.add(typeof(ClipboardGroup).name()); - descriptions.set(typeof(ClipboardGroup).name(), type_description); + if (type_description != null) { + types.add(typeof(ClipboardGroup).name()); + descriptions.set(typeof(ClipboardGroup).name(), type_description); + } type_description = DevicesGroup.register(); - types.add(typeof(DevicesGroup).name()); - descriptions.set(typeof(DevicesGroup).name(), type_description); + if (type_description != null) { + types.add(typeof(DevicesGroup).name()); + descriptions.set(typeof(DevicesGroup).name(), type_description); + } type_description = MenuGroup.register(); - types.add(typeof(MenuGroup).name()); - descriptions.set(typeof(MenuGroup).name(), type_description); + if (type_description != null) { + types.add(typeof(MenuGroup).name()); + descriptions.set(typeof(MenuGroup).name(), type_description); + } type_description = SessionGroup.register(); - types.add(typeof(SessionGroup).name()); - descriptions.set(typeof(SessionGroup).name(), type_description); + if (type_description != null) { + types.add(typeof(SessionGroup).name()); + descriptions.set(typeof(SessionGroup).name(), type_description); + } type_description = WindowListGroup.register(); - types.add(typeof(WindowListGroup).name()); - descriptions.set(typeof(WindowListGroup).name(), type_description); + if (type_description != null) { + types.add(typeof(WindowListGroup).name()); + descriptions.set(typeof(WindowListGroup).name(), type_description); + } } ///////////////////////////////////////////////////////////////////// @@ -83,6 +95,8 @@ public class GroupRegistry : GLib.Object { ///////////////////////////////////////////////////////////////////// public static ActionGroup? create_group(string type_id, string parent_id) { + bool wayland = GLib.Environment.get_variable("XDG_SESSION_TYPE") == "wayland"; + switch (type_id) { case "bookmarks": return new BookmarkGroup(parent_id); @@ -95,9 +109,11 @@ public class GroupRegistry : GLib.Object { case "session": return new SessionGroup(parent_id); case "window_list": + if (wayland) return null; return new WindowListGroup(parent_id); // deprecated case "workspace_window_list": + if (wayland) return null; var group = new WindowListGroup(parent_id); group.current_workspace_only = true; return group; diff --git a/src/actionGroups/menuGroup.vala b/src/actionGroups/menuGroup.vala index 353128f..92071d0 100644 --- a/src/actionGroups/menuGroup.vala +++ b/src/actionGroups/menuGroup.vala @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// Copyright (c) 2011-2016 by Simon Schneegans +// Copyright (c) 2011-2017 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 @@ -135,7 +135,8 @@ public class MenuGroup : ActionGroup { // get icon var icon = item.get_directory().get_icon(); - var sub_menu = PieManager.create_dynamic_pie(item.get_directory().get_name(), Icon.get_icon_name(icon)); + var sub_menu = PieManager.create_dynamic_pie(item.get_directory().get_name(), + icon.to_string()); var group = new MenuGroup.sub_menu(sub_menu.id); group.add_action(new PieAction(parent_id, true)); group.load_contents(item.get_directory(), sub_menu.id); diff --git a/src/actionGroups/sessionGroup.vala b/src/actionGroups/sessionGroup.vala index 5d47674..f044a72 100644 --- a/src/actionGroups/sessionGroup.vala +++ b/src/actionGroups/sessionGroup.vala @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// Copyright (c) 2011-2016 by Simon Schneegans +// Copyright (c) 2011-2017 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 diff --git a/src/actionGroups/windowListGroup.vala b/src/actionGroups/windowListGroup.vala index c3560af..c572f75 100644 --- a/src/actionGroups/windowListGroup.vala +++ b/src/actionGroups/windowListGroup.vala @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// Copyright (c) 2011-2016 by Simon Schneegans +// Copyright (c) 2011-2017 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 @@ -29,7 +29,12 @@ public class WindowListGroup : ActionGroup { /// the pies.conf file for this kind of ActionGroups. ///////////////////////////////////////////////////////////////////// - public static GroupRegistry.TypeDescription register() { + public static GroupRegistry.TypeDescription? register() { + if (GLib.Environment.get_variable("XDG_SESSION_TYPE") == "wayland") { + warning("The WindowList slice group is not supported on Wayland."); + return null; + } + var description = new GroupRegistry.TypeDescription(); description.name = _("Group: Window List"); description.icon = "preferences-system-windows"; @@ -41,12 +46,14 @@ public class WindowListGroup : ActionGroup { public bool current_workspace_only { get; set; default=false; } ///////////////////////////////////////////////////////////////////// - /// Two members needed to avoid useless, frequent changes of the - /// stored Actions. + /// Cached icon names loaded from .desktop files. ///////////////////////////////////////////////////////////////////// - private bool changing = false; - private bool changed_again = false; + private static Gee.HashMap<string, string> cached_icon_name { private get; private set; } + + ///////////////////////////////////////////////////////////////////// + /// Wnck's Screen object, to control the list of opened windows. + ///////////////////////////////////////////////////////////////////// private Wnck.Screen screen; @@ -56,24 +63,22 @@ public class WindowListGroup : ActionGroup { public WindowListGroup(string parent_id) { GLib.Object(parent_id : parent_id); - } - ///////////////////////////////////////////////////////////////////// - /// Loads all windows. - ///////////////////////////////////////////////////////////////////// + screen = Wnck.Screen.get_default(); + WindowListGroup.cached_icon_name = new Gee.HashMap<string, string>(); - construct { - this.screen = Wnck.Screen.get_default(); + Gtk.IconTheme.get_default().changed.connect(() => { + WindowListGroup.cached_icon_name = new Gee.HashMap<string, string>(); + create_actions_for_all_windows(); + }); - this.screen.window_opened.connect(reload); - this.screen.window_closed.connect(reload); - this.screen.active_workspace_changed.connect(reload); - - this.update(); + screen.active_workspace_changed.connect(create_actions_for_all_windows); + screen.window_opened.connect(create_action); + screen.window_closed.connect(remove_action); } ///////////////////////////////////////////////////////////////////// - /// This one is called, when the ActionGroup is saved. + /// This one is called when the ActionGroup is saved. ///////////////////////////////////////////////////////////////////// public override void on_save(Xml.TextWriter writer) { @@ -82,7 +87,7 @@ public class WindowListGroup : ActionGroup { } ///////////////////////////////////////////////////////////////////// - /// This one is called, when the ActionGroup is loaded. + /// This one is called when the ActionGroup is loaded. ///////////////////////////////////////////////////////////////////// public override void on_load(Xml.Node* data) { @@ -91,98 +96,117 @@ public class WindowListGroup : ActionGroup { string attr_content = attribute->children->content; if (attr_name == "current_workspace_only") { - this.current_workspace_only = bool.parse(attr_content); + current_workspace_only = bool.parse(attr_content); } } } ///////////////////////////////////////////////////////////////////// - /// Loads all currently opened windows and creates actions for them. + /// Remove a Action for a given window ///////////////////////////////////////////////////////////////////// - private void update() { - unowned GLib.List<Wnck.Window?> windows = this.screen.get_windows(); - - foreach (var window in windows) { - if (window.get_window_type() == Wnck.WindowType.NORMAL - && !window.is_skip_pager() && !window.is_skip_tasklist() - && (!current_workspace_only || (window.get_workspace() != null - && window.get_workspace() == this.screen.get_active_workspace()))) { - - var application = window.get_application(); - var icon = application.get_icon_name().down(); - var name = window.get_name(); - - if (name.length > 30) { - name = name.substring(0, 30) + "..."; + private void remove_action(Wnck.Window window) { + if (!window.is_skip_pager() && !window.is_skip_tasklist()) + foreach (Action action in actions) + if (window.get_xid() == uint64.parse(action.real_command)) { + actions.remove(action); + break; } + } - var action = new SigAction(name, icon, "%lu".printf(window.get_xid())); + ///////////////////////////////////////////////////////////////////// + /// Create Action's for all currently opened windows. + ///////////////////////////////////////////////////////////////////// - action.activated.connect((time_stamp) => { - Wnck.Screen.get_default().force_update(); + private void create_actions_for_all_windows() { + delete_all(); - var xid = (X.Window)uint64.parse(action.real_command); - var win = Wnck.Window.get(xid); + foreach (var window in screen.get_windows()) + create_action(window); + } - if (win.get_workspace() != null) { - //select the workspace - if (win.get_workspace() != win.get_screen().get_active_workspace()) { - win.get_workspace().activate(time_stamp); - } + ///////////////////////////////////////////////////////////////////// + /// Create a Action for a given opened window + ///////////////////////////////////////////////////////////////////// - //select the viewport inside the workspace - if (!win.is_in_viewport(win.get_workspace()) ) { - int xp, yp, widthp, heightp, scx, scy, nx, ny, wx, wy; - win.get_geometry (out xp, out yp, out widthp, out heightp); - scx = win.get_screen().get_width(); - scy = win.get_screen().get_height(); - wx = win.get_workspace().get_viewport_x(); - wy = win.get_workspace().get_viewport_y(); - if (scx > 0 && scy > 0) { - nx= ((wx+xp) / scx) * scx; - ny= ((wy+yp) / scy) * scy; - win.get_screen().move_viewport(nx, ny); - } - } - } + private void create_action(Wnck.Window window) { + if (!window.is_skip_pager() && !window.is_skip_tasklist() + && (!current_workspace_only || (window.get_workspace() != null + && window.get_workspace() == screen.get_active_workspace()))) { - if (win.is_minimized()) { - win.unminimize(time_stamp); - } + var name = window.get_name(); + var icon_name = get_icon_name(window); + var xid = "%lu".printf(window.get_xid()); - win.activate_transient(time_stamp); - }); - this.add_action(action); + if (name.length > 30) { + name = name.substring(0, 30) + "..."; } - } - } - ///////////////////////////////////////////////////////////////////// - /// Reloads all running applications. - ///////////////////////////////////////////////////////////////////// + var action = new SigAction(name, icon_name, xid); + this.add_action(action); - private void reload() { - // avoid too frequent changes... - if (!this.changing) { - this.changing = true; - Timeout.add(500, () => { - if (this.changed_again) { - this.changed_again = false; - return true; + window.name_changed.connect(() => { + action.name = window.get_name(); + }); + + action.activated.connect((time_stamp) => { + if (window.get_workspace() != null) { + //select the workspace + if (window.get_workspace() != window.get_screen().get_active_workspace()) { + window.get_workspace().activate(time_stamp); + } } - // reload - this.delete_all(); - this.update(); + if (window.is_minimized()) { + window.unminimize(time_stamp); + } - this.changing = false; - return false; + window.activate_transient(time_stamp); }); - } else { - this.changed_again = true; } } + + private string get_icon_name(Wnck.Window window) { + string icon_name = ""; + + #if HAVE_BAMF + var xid = (uint32) window.get_xid(); + Bamf.Matcher bamf_matcher = Bamf.Matcher.get_default(); + Bamf.Application app = bamf_matcher.get_application_for_xid(xid); + string desktop_file = null; + + if (app != null) + desktop_file = app.get_desktop_file(); + + if (desktop_file != null) { + if (WindowListGroup.cached_icon_name.has_key(desktop_file)) + icon_name = WindowListGroup.cached_icon_name.get(desktop_file); + else { + try { + var file = new KeyFile(); + file.load_from_file(desktop_file, 0); + + if (file.has_key(KeyFileDesktop.GROUP, KeyFileDesktop.KEY_ICON)) { + icon_name = file.get_locale_string(KeyFileDesktop.GROUP, KeyFileDesktop.KEY_ICON); + WindowListGroup.cached_icon_name.set(desktop_file, icon_name); + } + } catch (GLib.KeyFileError e) { + error("%s", e.message); + } catch (GLib.FileError e) { + error("%s", e.message); + } + } + } else { + var application = window.get_application(); + icon_name = application.get_icon_name().down(); + } + #else + var application = window.get_application(); + icon_name = application.get_icon_name().down(); + #endif + + return icon_name; + } } } diff --git a/src/actions/action.vala b/src/actions/action.vala index 555dc3c..6293302 100644 --- a/src/actions/action.vala +++ b/src/actions/action.vala @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// Copyright (c) 2011-2016 by Simon Schneegans +// Copyright (c) 2011-2017 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 diff --git a/src/actions/actionRegistry.vala b/src/actions/actionRegistry.vala index 579fc93..1640a1e 100644 --- a/src/actions/actionRegistry.vala +++ b/src/actions/actionRegistry.vala @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// Copyright (c) 2011-2016 by Simon Schneegans +// Copyright (c) 2011-2017 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 @@ -138,7 +138,7 @@ public class ActionRegistry : GLib.Object { // search for an appropriate icon var icon = info.get_icon(); - final_icon = Icon.get_icon_name(icon); + final_icon = icon.to_string(); } catch (GLib.Error e) { warning(e.message); @@ -147,9 +147,6 @@ public class ActionRegistry : GLib.Object { break; } - if (!Gtk.IconTheme.get_default().has_icon(final_icon)) - final_icon = "stock_unknown"; - if (name != null) final_name = name; @@ -164,7 +161,8 @@ public class ActionRegistry : GLib.Object { // get icon var icon = info.get_icon(); - return new AppAction(info.get_display_name(), Icon.get_icon_name(icon), info.get_commandline()); + return new AppAction(info.get_display_name(), icon.to_string(), + info.get_commandline()); } ///////////////////////////////////////////////////////////////////// diff --git a/src/actions/appAction.vala b/src/actions/appAction.vala index cc98c1e..4b55f91 100644 --- a/src/actions/appAction.vala +++ b/src/actions/appAction.vala @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// Copyright (c) 2011-2016 by Simon Schneegans +// Copyright (c) 2011-2017 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 diff --git a/src/actions/keyAction.vala b/src/actions/keyAction.vala index 41dab61..99418cd 100644 --- a/src/actions/keyAction.vala +++ b/src/actions/keyAction.vala @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// Copyright (c) 2011-2016 by Simon Schneegans +// Copyright (c) 2011-2017 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 diff --git a/src/actions/pieAction.vala b/src/actions/pieAction.vala index 806d63b..fe266dd 100644 --- a/src/actions/pieAction.vala +++ b/src/actions/pieAction.vala @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// Copyright (c) 2011-2016 by Simon Schneegans +// Copyright (c) 2011-2017 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 diff --git a/src/actions/sigAction.vala b/src/actions/sigAction.vala index fdde40a..fb241ca 100644 --- a/src/actions/sigAction.vala +++ b/src/actions/sigAction.vala @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// Copyright (c) 2011-2016 by Simon Schneegans +// Copyright (c) 2011-2017 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 diff --git a/src/actions/uriAction.vala b/src/actions/uriAction.vala index 2dde62d..74b3a15 100644 --- a/src/actions/uriAction.vala +++ b/src/actions/uriAction.vala @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// Copyright (c) 2011-2016 by Simon Schneegans +// Copyright (c) 2011-2017 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 diff --git a/src/daemon.vala b/src/daemon.vala index 0d111de..32f7e11 100644 --- a/src/daemon.vala +++ b/src/daemon.vala @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// Copyright (c) 2011-2016 by Simon Schneegans +// Copyright (c) 2011-2017 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 @@ -49,12 +49,14 @@ public class Daemon : GLib.Application { ///////////////////////////////////////////////////////////////////// public static int main(string[] args) { - version = "0.7.0"; + version = "0.7.1"; // disable overlay scrollbar --- hacky workaround for black / // transparent background GLib.Environment.set_variable("LIBOVERLAY_SCROLLBAR", "0", true); + Wnck.set_client_type(Wnck.ClientType.PAGER); + Logger.init(); Gtk.init(ref args); Paths.init(); diff --git a/src/gui/aboutWindow.vala b/src/gui/aboutWindow.vala index cddca63..da72417 100644 --- a/src/gui/aboutWindow.vala +++ b/src/gui/aboutWindow.vala @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// Copyright (c) 2011-2016 by Simon Schneegans +// Copyright (c) 2011-2017 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 @@ -33,7 +33,8 @@ public class AboutWindow: Gtk.AboutDialog { "Simon Schneegans <code@simonschneegans.de>", "Gabriel Dubatti <gdubatti@gmail.com>", "Francesco Piccinno <stack.box@gmail.com>", - "György Balló <ballogyor@gmail.com>" + "György Balló <ballogyor@gmail.com>", + "Tiago de Oliveira Corrêa <tcorreabr@gmail.com>" }; string[] artists = { "Simon Schneegans <code@simonschneegans.de>" @@ -50,6 +51,7 @@ public class AboutWindow: Gtk.AboutDialog { "Raphaël Rochet <raphael@rri.fr> (FR)", "Alex Maxime <cad.maxime@gmail.com> (FR)", "Eugene Roskin <pams@imail.ru> (RU)", + "Ashed <craysy@gmail.com> (RU)", "Ting Zhou <tzhou@haverford.edu> (ZH-CN)", "Martin Dinov <martindinov@yahoo.com> (BG)" }; @@ -71,7 +73,7 @@ public class AboutWindow: Gtk.AboutDialog { artists : artists, authors : devs, translator_credits : translator_string, - copyright : "Copyright (C) 2011-2015 Simon Schneegans <code@simonschneegans.de>", + copyright : "Copyright (C) 2011-2017 Simon Schneegans <code@simonschneegans.de>", program_name: "Gnome-Pie", logo_icon_name: "gnome-pie", website: "http://simmesimme.github.io/gnome-pie.html", diff --git a/src/gui/commandComboList.vala b/src/gui/commandComboList.vala index 3f157ce..640c7b7 100644 --- a/src/gui/commandComboList.vala +++ b/src/gui/commandComboList.vala @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// Copyright (c) 2011-2016 by Simon Schneegans +// Copyright (c) 2011-2017 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 diff --git a/src/gui/iconSelectWindow.vala b/src/gui/iconSelectWindow.vala index d7e5062..6776288 100644 --- a/src/gui/iconSelectWindow.vala +++ b/src/gui/iconSelectWindow.vala @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// Copyright (c) 2011-2016 by Simon Schneegans +// Copyright (c) 2011-2017 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 @@ -106,7 +106,6 @@ public class IconSelectWindow : GLib.Object { private class ListEntry { public string name; - public IconContext context; public Gdk.Pixbuf pixbuf; } @@ -119,20 +118,6 @@ public class IconSelectWindow : GLib.Object { private GLib.AsyncQueue<ListEntry?> load_queue; ///////////////////////////////////////////////////////////////////// - /// Possible icon types. - ///////////////////////////////////////////////////////////////////// - - private enum IconContext { - ALL, - APPS, - ACTIONS, - PLACES, - FILES, - EMOTES, - OTHER - } - - ///////////////////////////////////////////////////////////////////// /// C'tor, creates a new IconSelectWindow. ///////////////////////////////////////////////////////////////////// @@ -141,9 +126,8 @@ public class IconSelectWindow : GLib.Object { this.load_queue = new GLib.AsyncQueue<ListEntry?>(); if (IconSelectWindow.icon_list == null) { - IconSelectWindow.icon_list = new Gtk.ListStore(3, typeof(string), // icon name - typeof(IconContext), // icon type - typeof(Gdk.Pixbuf)); // the icon itself + IconSelectWindow.icon_list = new Gtk.ListStore(2, typeof(string), // icon name + typeof(Gdk.Pixbuf)); // the icon itself // disable sorting until all icons are loaded // else loading becomes horribly slow @@ -175,26 +159,6 @@ public class IconSelectWindow : GLib.Object { (builder.get_object("ok-button") as Gtk.Button).clicked.connect(on_ok_button_clicked); (builder.get_object("cancel-button") as Gtk.Button).clicked.connect(on_cancel_button_clicked); - var combo_box = builder.get_object("combo-box") as Gtk.Box; - - // context combo - var context_combo = new Gtk.ComboBoxText(); - context_combo.append_text(_("All icons")); - context_combo.append_text(_("Applications")); - context_combo.append_text(_("Actions")); - context_combo.append_text(_("Places")); - context_combo.append_text(_("File types")); - context_combo.append_text(_("Emotes")); - context_combo.append_text(_("Miscellaneous")); - - context_combo.set_active(0); - - context_combo.changed.connect(() => { - this.icon_list_filtered.refilter(); - }); - - combo_box.pack_start(context_combo, false, false); - // string filter entry var filter = builder.get_object("filter-entry") as Gtk.Entry; @@ -202,21 +166,16 @@ public class IconSelectWindow : GLib.Object { // and whose name contains the text entered in the entry this.icon_list_filtered.set_visible_func((model, iter) => { string name = ""; - IconContext context = IconContext.ALL; model.get(iter, 0, out name); - model.get(iter, 1, out context); - if (name == null) return false; - - return (context_combo.get_active() == context || - context_combo.get_active() == IconContext.ALL) && - name.down().contains(filter.text.down()); + return name.down().contains(filter.text.down()); }); // clear when the users clicks on the "clear" icon filter.icon_release.connect((pos, event) => { - if (pos == Gtk.EntryIconPosition.SECONDARY) + if (pos == Gtk.EntryIconPosition.SECONDARY) { filter.text = ""; + } }); // refilter on input @@ -231,7 +190,7 @@ public class IconSelectWindow : GLib.Object { this.icon_view = new Gtk.IconView.with_model(this.icon_list_filtered); this.icon_view.item_width = 32; this.icon_view.item_padding = 2; - this.icon_view.pixbuf_column = 2; + this.icon_view.pixbuf_column = 1; this.icon_view.tooltip_column = 0; // set active_icon if selection changes @@ -376,8 +335,7 @@ public class IconSelectWindow : GLib.Object { Gtk.TreeIter current; IconSelectWindow.icon_list.append(out current); IconSelectWindow.icon_list.set(current, 0, new_entry.name, - 1, new_entry.context, - 2, new_entry.pixbuf); + 1, new_entry.pixbuf); } // enable sorting of the icon_view if loading finished @@ -397,44 +355,20 @@ public class IconSelectWindow : GLib.Object { private async void load_all() { var icon_theme = Gtk.IconTheme.get_default(); + foreach (var icon in icon_theme.list_icons(null)) { + Idle.add(load_all.callback); + yield; - foreach (var context in icon_theme.list_contexts()) { - if (!disabled_contexts.contains(context)) { - foreach (var icon in icon_theme.list_icons(context)) { - - IconContext icon_context = IconContext.OTHER; - switch(context) { - case "Apps": case "Applications": - icon_context = IconContext.APPS; break; - case "Emotes": - icon_context = IconContext.EMOTES; break; - case "Places": case "Devices": - icon_context = IconContext.PLACES; break; - case "Mimetypes": - icon_context = IconContext.FILES; break; - case "Actions": - icon_context = IconContext.ACTIONS; break; - default: break; - } - - Idle.add(load_all.callback); - yield; - - try { - // create a new entry for the queue - var new_entry = new ListEntry(); - new_entry.name = icon; - new_entry.context = icon_context; - new_entry.pixbuf = icon_theme.load_icon(icon, 32, 0); + try { + // create a new entry for the queue + var new_entry = new ListEntry(); + new_entry.name = icon; + new_entry.pixbuf = icon_theme.load_icon(icon, 32, Gtk.IconLookupFlags.FORCE_SIZE); - // some icons have only weird sizes... do not include them - if (new_entry.pixbuf.width == 32) - this.load_queue.push(new_entry); + this.load_queue.push(new_entry); - } catch (GLib.Error e) { - warning("Failed to load image " + icon); - } - } + } catch (GLib.Error e) { + warning("Failed to load image " + icon); } } @@ -442,8 +376,9 @@ public class IconSelectWindow : GLib.Object { IconSelectWindow.loading = false; // hide the spinner - if (spinner != null) + if (spinner != null) { spinner.visible = false; + } } } diff --git a/src/gui/indicator.vala b/src/gui/indicator.vala index 55baaf1..ddd101b 100644 --- a/src/gui/indicator.vala +++ b/src/gui/indicator.vala @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// Copyright (c) 2011-2016 by Simon Schneegans +// Copyright (c) 2011-2017 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 @@ -68,13 +68,6 @@ public class Indicator : GLib.Object { public Indicator() { string icon = "gnome-pie-symbolic"; - var screen = (Gdk.X11.Screen)Gdk.Screen.get_default(); - bool gnome_shell = false; - - if (screen.get_window_manager_name() == "GNOME Shell") { - icon = "gnome-pie"; - gnome_shell = true; - } #if HAVE_APPINDICATOR @@ -85,19 +78,9 @@ public class Indicator : GLib.Object { warning("Failed to get path of executable!"); } - if (gnome_shell) { - - if (GLib.File.new_for_path(path).query_exists()) { - this.indicator = new AppIndicator.Indicator("Gnome-Pie", path + "/" + icon + ".svg", - AppIndicator.IndicatorCategory.APPLICATION_STATUS); - } else { - this.indicator = new AppIndicator.Indicator("Gnome-Pie", icon, - AppIndicator.IndicatorCategory.APPLICATION_STATUS); - } - } else { - this.indicator = new AppIndicator.Indicator.with_path("Gnome-Pie", icon, - AppIndicator.IndicatorCategory.APPLICATION_STATUS, path); - } + this.indicator = new AppIndicator.Indicator.with_path("Gnome-Pie", icon, + AppIndicator.IndicatorCategory.APPLICATION_STATUS, path); + var menu = new Gtk.Menu(); #else this.indicator = new Gtk.StatusIcon(); diff --git a/src/gui/newSliceWindow.vala b/src/gui/newSliceWindow.vala index 3133e34..6ea25d5 100644 --- a/src/gui/newSliceWindow.vala +++ b/src/gui/newSliceWindow.vala @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// Copyright (c) 2011-2016 by Simon Schneegans +// Copyright (c) 2011-2017 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 diff --git a/src/gui/newsWindow.vala b/src/gui/newsWindow.vala index 2ab13c0..f359ae9 100644 --- a/src/gui/newsWindow.vala +++ b/src/gui/newsWindow.vala @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// Copyright (c) 2011-2016 by Simon Schneegans +// Copyright (c) 2011-2017 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 @@ -23,7 +23,7 @@ namespace GnomePie { public class NewsWindow: Gtk.Dialog { - public static const int news_count = 2; + public const int news_count = 2; ///////////////////////////////////////////////////////////////////// /// diff --git a/src/gui/pieComboList.vala b/src/gui/pieComboList.vala index 6a5c172..96230c0 100644 --- a/src/gui/pieComboList.vala +++ b/src/gui/pieComboList.vala @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// Copyright (c) 2011-2016 by Simon Schneegans +// Copyright (c) 2011-2017 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 diff --git a/src/gui/pieList.vala b/src/gui/pieList.vala index ed93098..1f6ccec 100644 --- a/src/gui/pieList.vala +++ b/src/gui/pieList.vala @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// Copyright (c) 2011-2016 by Simon Schneegans +// Copyright (c) 2011-2017 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 diff --git a/src/gui/pieOptionsWindow.vala b/src/gui/pieOptionsWindow.vala index 5440305..ea50a53 100644 --- a/src/gui/pieOptionsWindow.vala +++ b/src/gui/pieOptionsWindow.vala @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// Copyright (c) 2011-2016 by Simon Schneegans +// Copyright (c) 2011-2017 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 @@ -46,6 +46,8 @@ public class PieOptionsWindow : GLib.Object { private Gtk.Button? icon_button = null; private Gtk.Image? icon = null; private Gtk.Label? pie_id = null; + private Gtk.Label? hint = null; + private Gtk.Frame? optionsFrame = null; private IconSelectWindow? icon_window = null; @@ -141,6 +143,10 @@ public class PieOptionsWindow : GLib.Object { this.icon_button = builder.get_object("icon-button") as Gtk.Button; this.icon_button.clicked.connect(on_icon_button_clicked); + this.hint = builder.get_object("hint") as Gtk.Label; + + this.optionsFrame = builder.get_object("optionsFrame") as Gtk.Frame; + this.window.delete_event.connect(this.window.hide_on_delete); } catch (GLib.Error e) { @@ -163,6 +169,10 @@ public class PieOptionsWindow : GLib.Object { public void show() { this.window.show_all(); + + if (GLib.Environment.get_variable("XDG_SESSION_TYPE") == "wayland") { + this.optionsFrame.visible = false; + } } ///////////////////////////////////////////////////////////////////// @@ -187,6 +197,15 @@ public class PieOptionsWindow : GLib.Object { this.pie_id.label = "Pie-ID: " + id; this.trigger_button.set_trigger(trigger); this.set_icon(pie.icon); + + if (GLib.Environment.get_variable("XDG_SESSION_TYPE") == "wayland") { + this.trigger_button.set_sensitive(false); + + this.hint.set_line_wrap(true); + this.hint.set_max_width_chars(40); + this.hint.set_justify(Gtk.Justification.RIGHT); + this.hint.set_label(_("Keybindings and some other options are not supported on Wayland. However, you can use the terminial command \"gnome-pie --open %s\" to open this pie. Create a global hotkey in your system settings which executes this command!").printf(id)); + } } ///////////////////////////////////////////////////////////////////// diff --git a/src/gui/piePreview.vala b/src/gui/piePreview.vala index 540ab51..6c23590 100644 --- a/src/gui/piePreview.vala +++ b/src/gui/piePreview.vala @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// Copyright (c) 2011-2016 by Simon Schneegans +// Copyright (c) 2011-2017 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 @@ -170,10 +170,7 @@ class PiePreview : Gtk.DrawingArea { ///////////////////////////////////////////////////////////////////// public void set_pie(string id) { - var style = this.get_style_context(); - this.current_id = id; - this.override_background_color(Gtk.StateFlags.NORMAL, style.get_background_color(Gtk.StateFlags.NORMAL)); this.renderer.load_pie(PieManager.all_pies[id]); if (id == this.drag_start_id) { diff --git a/src/gui/piePreviewAddSign.vala b/src/gui/piePreviewAddSign.vala index b5bbe53..2674879 100644 --- a/src/gui/piePreviewAddSign.vala +++ b/src/gui/piePreviewAddSign.vala @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// Copyright (c) 2011-2016 by Simon Schneegans +// Copyright (c) 2011-2017 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 diff --git a/src/gui/piePreviewCenter.vala b/src/gui/piePreviewCenter.vala index 2da47e6..2e9923e 100644 --- a/src/gui/piePreviewCenter.vala +++ b/src/gui/piePreviewCenter.vala @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// Copyright (c) 2011-2016 by Simon Schneegans +// Copyright (c) 2011-2017 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 diff --git a/src/gui/piePreviewDeleteSign.vala b/src/gui/piePreviewDeleteSign.vala index 05afd5b..0b63aa6 100644 --- a/src/gui/piePreviewDeleteSign.vala +++ b/src/gui/piePreviewDeleteSign.vala @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// Copyright (c) 2011-2016 by Simon Schneegans +// Copyright (c) 2011-2017 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 @@ -42,9 +42,9 @@ public class PiePreviewDeleteSign : GLib.Object { /// Some constants determining the look and behaviour of this Slice. ///////////////////////////////////////////////////////////////////// - private static const int radius = 18; - private static const double globale_scale = 0.8; - private static const double click_cancel_treshold = 5; + private const int radius = 18; + private const double globale_scale = 0.8; + private const double click_cancel_treshold = 5; ///////////////////////////////////////////////////////////////////// /// True, when the add sign is currently visible. diff --git a/src/gui/piePreviewRenderer.vala b/src/gui/piePreviewRenderer.vala index dbd929a..d7dad25 100644 --- a/src/gui/piePreviewRenderer.vala +++ b/src/gui/piePreviewRenderer.vala @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// Copyright (c) 2011-2016 by Simon Schneegans +// Copyright (c) 2011-2017 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 diff --git a/src/gui/piePreviewSliceRenderer.vala b/src/gui/piePreviewSliceRenderer.vala index 35cb0a2..622e0dd 100644 --- a/src/gui/piePreviewSliceRenderer.vala +++ b/src/gui/piePreviewSliceRenderer.vala @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// Copyright (c) 2011-2016 by Simon Schneegans +// Copyright (c) 2011-2017 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 @@ -72,11 +72,11 @@ public class PiePreviewSliceRenderer : GLib.Object { /// Some constants determining the look and behaviour of this Slice. ///////////////////////////////////////////////////////////////////// - private static const double pie_radius = 126; - private static const double radius = 24; - private static const double delete_x = 13; - private static const double delete_y = -13; - private static const double click_cancel_treshold = 5; + private const double pie_radius = 126; + private const double radius = 24; + private const double delete_x = 13; + private const double delete_y = -13; + private const double click_cancel_treshold = 5; ///////////////////////////////////////////////////////////////////// /// Storing the position where a mouse click was executed. Useful for diff --git a/src/gui/preferencesWindow.vala b/src/gui/preferencesWindow.vala index 1fedfb2..8c6c66c 100644 --- a/src/gui/preferencesWindow.vala +++ b/src/gui/preferencesWindow.vala @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// Copyright (c) 2011-2016 by Simon Schneegans +// Copyright (c) 2011-2017 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 @@ -163,7 +163,7 @@ public class PreferencesWindow : GLib.Object { (builder.get_object("theme-help-button") as Gtk.Button).clicked.connect(() => { try{ - GLib.AppInfo.launch_default_for_uri("http://simmesimme.github.io/lessons/2015/04/26/themes-for-gnome-pie/", null); + GLib.AppInfo.launch_default_for_uri("http://simmesimme.github.io/lessons/2015/04/26/themes-for-gnome-pie", null); } catch (Error e) { warning(e.message); } @@ -281,9 +281,6 @@ public class PreferencesWindow : GLib.Object { this.window.show_all(); this.pie_list.select_first(); - var style = this.preview_background.get_style_context(); - this.preview_background.override_background_color(Gtk.StateFlags.NORMAL, style.get_background_color(Gtk.StateFlags.NORMAL)); - this.indicator.active = Config.global.show_indicator; this.autostart.active = Config.global.auto_start; this.captions.active = Config.global.show_captions; @@ -532,15 +529,17 @@ public class PreferencesWindow : GLib.Object { } else { var pie = PieManager.all_pies[selected_id]; - this.preview.set_pie(id); - this.preview_box.show(); + if (pie != null) { + this.preview.set_pie(id); + this.preview_box.show(); - if (pie.action_groups.size == 0) { - this.no_slice_label.show(); - } + if (pie.action_groups.size == 0) { + this.no_slice_label.show(); + } - this.remove_pie_button.sensitive = true; - this.edit_pie_button.sensitive = true; + this.remove_pie_button.sensitive = true; + this.edit_pie_button.sensitive = true; + } } } diff --git a/src/gui/sliceTypeList.vala b/src/gui/sliceTypeList.vala index 2dcf16b..cec9ce3 100644 --- a/src/gui/sliceTypeList.vala +++ b/src/gui/sliceTypeList.vala @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// Copyright (c) 2011-2016 by Simon Schneegans +// Copyright (c) 2011-2017 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 diff --git a/src/gui/themeList.vala b/src/gui/themeList.vala index 8e7b190..022b57d 100644 --- a/src/gui/themeList.vala +++ b/src/gui/themeList.vala @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// Copyright (c) 2011-2016 by Simon Schneegans +// Copyright (c) 2011-2017 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 diff --git a/src/gui/tipViewer.vala b/src/gui/tipViewer.vala index e484315..24b4ccc 100644 --- a/src/gui/tipViewer.vala +++ b/src/gui/tipViewer.vala @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// Copyright (c) 2011-2016 by Simon Schneegans +// Copyright (c) 2011-2017 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 @@ -69,8 +69,6 @@ public class TipViewer : Gtk.Label { this.wrap = true; this.valign = Gtk.Align.END; this.set_use_markup(true); - - this.override_font(Pango.FontDescription.from_string("8")); } ///////////////////////////////////////////////////////////////////// @@ -155,7 +153,7 @@ public class TipViewer : Gtk.Label { next_index = GLib.Random.int_range(0, tips.length); } while (next_index == this.index); this.index = next_index; - this.label = tips[this.index]; + this.label = "<small>" + tips[this.index] + "</small>"; } } } diff --git a/src/gui/triggerSelectButton.vala b/src/gui/triggerSelectButton.vala index c870f84..c70f1cd 100644 --- a/src/gui/triggerSelectButton.vala +++ b/src/gui/triggerSelectButton.vala @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// Copyright (c) 2011-2016 by Simon Schneegans +// Copyright (c) 2011-2017 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 @@ -63,7 +63,7 @@ public class TriggerSelectButton : Gtk.ToggleButton { if (this.active) { this.set_label(_("Press a hotkey ...")); Gtk.grab_add(this); - FocusGrabber.grab(this.get_window(), true, true, true); + FocusGrabber.grab(this.get_window()); } }); @@ -89,7 +89,7 @@ public class TriggerSelectButton : Gtk.ToggleButton { this.set_label(trigger.label); this.set_active(false); Gtk.grab_remove(this); - FocusGrabber.ungrab(true, true); + FocusGrabber.ungrab(); } ///////////////////////////////////////////////////////////////////// diff --git a/src/images/icon.vala b/src/images/icon.vala index 176e187..7933e81 100644 --- a/src/images/icon.vala +++ b/src/images/icon.vala @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// Copyright (c) 2011-2016 by Simon Schneegans +// Copyright (c) 2011-2017 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 @@ -75,60 +75,43 @@ public class Icon : Image { } ///////////////////////////////////////////////////////////////////// - /// Returns the icon name for a given GLib.Icon. - ///////////////////////////////////////////////////////////////////// - - public static string get_icon_name(GLib.Icon? icon) { - if (icon != null) { - var icon_names = icon.to_string().split(" "); - - foreach (var icon_name in icon_names) { - if (Gtk.IconTheme.get_default().has_icon(icon_name)) { - return icon_name; - } - } - } - - return ""; - } - - ///////////////////////////////////////////////////////////////////// /// Returns the filename for a given system icon. ///////////////////////////////////////////////////////////////////// public static string get_icon_file(string icon_name, int size) { - string result = ""; - if (icon_name.contains("/")) { var file = GLib.File.new_for_path(icon_name); - if(file.query_exists()) + if(file.query_exists()) { return icon_name; - - warning("Icon \"" + icon_name + "\" not found! Using default icon..."); + } } - var icon_theme = Gtk.IconTheme.get_default(); var file = icon_theme.lookup_icon(icon_name, size, 0); - if (file != null) result = file.get_filename(); - - if (result == "") { - warning("Icon \"" + icon_name + "\" not found! Using default icon..."); - - string[] default_icons = {"application-default-icon", "stock_unknown"}; - foreach (var icon in default_icons) { - file = icon_theme.lookup_icon(icon, size, 0); - if (file != null) { - result = file.get_filename(); - break; - } + if (file != null) { + return file.get_filename(); + } + + try { + file = icon_theme.lookup_by_gicon(GLib.Icon.new_for_string(icon_name), size, 0); + if (file != null) { + return file.get_filename(); } + } catch(GLib.Error e) {} + + warning("Icon \"" + icon_name + "\" not found! Using default icon..."); - if (result == "") - warning("No default icon found! Will be ugly..."); + string[] default_icons = {"image-missing", "application-default-icon"}; + foreach (var icon in default_icons) { + file = icon_theme.lookup_icon(icon, size, 0); + if (file != null) { + return file.get_filename(); + } } - return result; + warning("No default icon found! Will be ugly..."); + + return ""; } } diff --git a/src/images/image.vala b/src/images/image.vala index 840a8ad..9a00f45 100644 --- a/src/images/image.vala +++ b/src/images/image.vala @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// Copyright (c) 2011-2016 by Simon Schneegans +// Copyright (c) 2011-2017 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 diff --git a/src/images/renderedText.vala b/src/images/renderedText.vala index f00c8b5..cae6ee3 100644 --- a/src/images/renderedText.vala +++ b/src/images/renderedText.vala @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// Copyright (c) 2011-2016 by Simon Schneegans +// Copyright (c) 2011-2017 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 diff --git a/src/images/themedIcon.vala b/src/images/themedIcon.vala index 9dd9609..6ab5741 100644 --- a/src/images/themedIcon.vala +++ b/src/images/themedIcon.vala @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// Copyright (c) 2011-2016 by Simon Schneegans +// Copyright (c) 2011-2017 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 diff --git a/src/pies/defaultConfig.vala b/src/pies/defaultConfig.vala index 4041111..d832347 100644 --- a/src/pies/defaultConfig.vala +++ b/src/pies/defaultConfig.vala @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// Copyright (c) 2011-2016 by Simon Schneegans +// Copyright (c) 2011-2017 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 @@ -63,8 +63,10 @@ namespace Pies { window.add_action(new KeyAction(_("Restore"), "view-restore", "<Alt>F5")); // add a pie with window list group - var alt_tab = PieManager.create_persistent_pie("Alt Tab", "dock", new Trigger.from_string("<Control><Alt>T")); + if (GLib.Environment.get_variable("XDG_SESSION_TYPE") != "wayland") { + var alt_tab = PieManager.create_persistent_pie("Alt Tab", "preferences-system-windows", new Trigger.from_string("<Control><Alt>T")); alt_tab.add_group(new WindowListGroup(alt_tab.id)); + } // save the configuration to file Pies.save(); diff --git a/src/pies/load.vala b/src/pies/load.vala index 20e18d8..976d818 100644 --- a/src/pies/load.vala +++ b/src/pies/load.vala @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// Copyright (c) 2011-2016 by Simon Schneegans +// Copyright (c) 2011-2017 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 @@ -199,9 +199,11 @@ namespace Pies { } ActionGroup group = GroupRegistry.create_group(type, pie.id); - group.on_load(slice); - if (group != null) pie.add_group(group); + if (group != null) { + group.on_load(slice); + pie.add_group(group); + } } } diff --git a/src/pies/pie.vala b/src/pies/pie.vala index be17238..ef5549c 100644 --- a/src/pies/pie.vala +++ b/src/pies/pie.vala @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// Copyright (c) 2011-2016 by Simon Schneegans +// Copyright (c) 2011-2017 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 diff --git a/src/pies/pieManager.vala b/src/pies/pieManager.vala index d9bf5b7..6951508 100644 --- a/src/pies/pieManager.vala +++ b/src/pies/pieManager.vala @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// Copyright (c) 2011-2016 by Simon Schneegans +// Copyright (c) 2011-2017 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 diff --git a/src/pies/save.vala b/src/pies/save.vala index 0a2d401..2c5e191 100644 --- a/src/pies/save.vala +++ b/src/pies/save.vala @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// Copyright (c) 2011-2016 by Simon Schneegans +// Copyright (c) 2011-2017 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 diff --git a/src/renderers/centerRenderer.vala b/src/renderers/centerRenderer.vala index 88b569c..65a28fa 100644 --- a/src/renderers/centerRenderer.vala +++ b/src/renderers/centerRenderer.vala @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// Copyright (c) 2011-2016 by Simon Schneegans +// Copyright (c) 2011-2017 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 @@ -188,8 +188,9 @@ public class CenterRenderer : GLib.Object { // draw caption if (Config.global.theme.caption && caption != null && this.activity.val > 0) { ctx.save(); - ctx.identity_matrix(); - ctx.translate(this.parent.center_x, (int)(Config.global.theme.caption_position) + this.parent.center_y); + double x, y; + ctx.get_current_point(out x, out y); + ctx.move_to(GLib.Math.floor(x), GLib.Math.floor(y)); caption.paint_on(ctx, this.activity.val*this.alpha.val); ctx.restore(); } diff --git a/src/renderers/pieRenderer.vala b/src/renderers/pieRenderer.vala index 32f3a5f..47d8b8e 100644 --- a/src/renderers/pieRenderer.vala +++ b/src/renderers/pieRenderer.vala @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// Copyright (c) 2011-2016 by Simon Schneegans +// Copyright (c) 2011-2017 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 @@ -175,28 +175,6 @@ public class PieRenderer : GLib.Object { set_show_mode(ShowPieMode.FULL_PIE); } - - private void get_mouse_and_screen(out int mousex, out int mousey, out int screenx, out int screeny) { - // get the mouse position and screen resolution - double x = 0.0; - double y = 0.0; - - 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) { - Gdk.Screen screen; - device.get_position( out screen, out x, out y ); - } - } - mousex= (int) x; - mousey= (int) y; - screenx= Gdk.Screen.width(); - screeny= Gdk.Screen.height(); - } - ///////////////////////////////////////////////////////////////////// /// Loads a Pie. All members are initialized accordingly. ///////////////////////////////////////////////////////////////////// @@ -239,12 +217,40 @@ public class PieRenderer : GLib.Object { + Config.global.theme.visible_slice_radius)*2*Config.global.theme.max_zoom); } - - - // get mouse position and screen resolution - int mouse_x, mouse_y, screen_x, screen_y; - get_mouse_and_screen( out mouse_x, out mouse_y, out screen_x, out screen_y ); + int mouse_x, mouse_y; + + #if HAVE_GTK_3_20 + var seat = Gdk.Display.get_default().get_default_seat(); + seat.get_pointer().get_position(null, out mouse_x, out mouse_y); + #else + double x = 0.0; + double y = 0.0; + + 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) { + Gdk.Screen screen; + device.get_position( out screen, out x, out y ); + } + } + + mouse_x = (int) x; + mouse_y = (int) y; + #endif + + #if HAVE_GTK_3_22 + var monitor = Gdk.Display.get_default().get_monitor_at_point(mouse_x, mouse_y).get_geometry(); + int monitor_x = monitor.width; + int monitor_y = monitor.height; + #else + var screen = Gdk.Screen.get_default().get_root_window(); + int monitor_x = screen.get_width(); + int monitor_y = screen.get_height(); + #endif //reduce the window size if needed to get closer to the actual mouse position int reduce_szx= 1; @@ -255,24 +261,24 @@ public class PieRenderer : GLib.Object { if (mouse_x < sz/2) { if (mouse_y < sz/2) showpie= ShowPieMode.CPIE_TOP_LEFT; //show 1/4 pie - else if (screen_y > 0 && screen_y-mouse_y < sz/2) + else if (monitor_y > 0 && monitor_y-mouse_y < sz/2) showpie= ShowPieMode.CPIE_BOT_LEFT; //show 1/4 pie else showpie= ShowPieMode.HPIE_LEFT; //show 1/2 pie } else if (mouse_y < sz/2) { - if (screen_x > 0 && screen_x-mouse_x < sz/2) + if (monitor_x > 0 && monitor_x-mouse_x < sz/2) showpie= ShowPieMode.CPIE_TOP_RIGHT; //show 1/4 pie else showpie= ShowPieMode.HPIE_TOP; //show 1/2 pie - } else if (screen_x > 0 && screen_x-mouse_x < sz/2) { - if (screen_y > 0 && screen_y-mouse_y < sz/2) + } else if (monitor_x > 0 && monitor_x-mouse_x < sz/2) { + if (monitor_y > 0 && monitor_y-mouse_y < sz/2) showpie= ShowPieMode.CPIE_BOT_RIGHT; //show 1/4 pie else showpie= ShowPieMode.HPIE_RIGHT; //show 1/2 pie - } else if (screen_y > 0 && screen_y-mouse_y < sz/2) + } else if (monitor_y > 0 && monitor_y-mouse_y < sz/2) showpie= ShowPieMode.HPIE_BOTTOM; //show 1/2 pie @@ -288,26 +294,26 @@ public class PieRenderer : GLib.Object { switch( PieManager.get_shape_number(pie.id) ) { case 1: showpie= ShowPieMode.CPIE_BOT_RIGHT; - if (screen_x-mouse_x > sz/2) + if (monitor_x-mouse_x > sz/2) reduce_szx= 0; //keep full width - if (screen_y-mouse_y > sz/2) + if (monitor_y-mouse_y > sz/2) reduce_szy= 0; //keep full height break; case 2: showpie= ShowPieMode.HPIE_RIGHT; - if (screen_x-mouse_x > sz/2) + if (monitor_x-mouse_x > sz/2) reduce_szx= 0; //keep full width break; case 3: showpie= ShowPieMode.CPIE_TOP_RIGHT; - if (screen_x-mouse_x > sz/2) + if (monitor_x-mouse_x > sz/2) reduce_szx= 0; //keep full width if (mouse_y > sz/2) reduce_szy= 0; //keep full height break; case 4: showpie= ShowPieMode.HPIE_BOTTOM; - if (screen_y-mouse_y > sz/2) + if (monitor_y-mouse_y > sz/2) reduce_szy= 0; //keep full height break; case 6: @@ -319,7 +325,7 @@ public class PieRenderer : GLib.Object { showpie= ShowPieMode.CPIE_BOT_LEFT; if (mouse_x > sz/2) reduce_szx= 0; //keep full width - if (screen_y-mouse_y > sz/2) + if (monitor_y-mouse_y > sz/2) reduce_szy= 0; //keep full height break; case 8: diff --git a/src/renderers/pieWindow.vala b/src/renderers/pieWindow.vala index d2bf61f..a5142df 100644 --- a/src/renderers/pieWindow.vala +++ b/src/renderers/pieWindow.vala @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// Copyright (c) 2011-2016 by Simon Schneegans +// Copyright (c) 2011-2017 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 @@ -102,6 +102,12 @@ public class PieWindow : Gtk.Window { private string search_string = ""; ///////////////////////////////////////////////////////////////////// + /// Used to identify wayland sessions. + ///////////////////////////////////////////////////////////////////// + + private bool wayland = GLib.Environment.get_variable("XDG_SESSION_TYPE") == "wayland"; + + ///////////////////////////////////////////////////////////////////// /// C'tor, sets up the window. ///////////////////////////////////////////////////////////////////// @@ -112,7 +118,7 @@ public class PieWindow : Gtk.Window { this.set_skip_taskbar_hint(true); this.set_skip_pager_hint(true); this.set_keep_above(true); - this.set_type_hint(Gdk.WindowTypeHint.POPUP_MENU); + this.set_type_hint(Gdk.WindowTypeHint.DOCK); this.set_decorated(false); this.set_resizable(false); this.icon_name = "gnome-pie"; @@ -186,8 +192,7 @@ public class PieWindow : Gtk.Window { }); this.show.connect_after(() => { - Gtk.grab_add(this); - FocusGrabber.grab(this.get_window(), true, true, false); + FocusGrabber.grab(this.get_window()); }); this.scroll_event.connect((e) => { @@ -209,8 +214,25 @@ public class PieWindow : Gtk.Window { public void load_pie(Pie pie) { this.renderer.load_pie(pie); - this.set_window_position(pie); - this.set_size_request(renderer.size_w, renderer.size_h); + + if (wayland) { + // wayland does not support client side window placement + // therefore we will make a fullscreen window + #if HAVE_GTK_3_22 + var monitor = Gdk.Display.get_default().get_monitor_at_point(this.back_x, this.back_y).get_geometry(); + int monitor_x = monitor.width; + int monitor_y = monitor.height; + #else + var screen = Gdk.Screen.get_default().get_root_window(); + int monitor_x = screen.get_width(); + int monitor_y = screen.get_height(); + #endif + + this.set_size_request(monitor_x, monitor_y); + } else { + this.set_window_position(pie); + this.set_size_request(renderer.size_w, renderer.size_h); + } } ///////////////////////////////////////////////////////////////////// @@ -226,15 +248,22 @@ public class PieWindow : Gtk.Window { this.back_sz_x++; this.back_sz_y++; - int screenx= Gdk.Screen.width(); - int screeny= Gdk.Screen.height(); + #if HAVE_GTK_3_22 + var monitor = Gdk.Display.get_default().get_monitor_at_point(this.back_x, this.back_y).get_geometry(); + int monitor_x = monitor.width; + int monitor_y = monitor.height; + #else + var screen = Gdk.Screen.get_default().get_root_window(); + int monitor_x = screen.get_width(); + int monitor_y = screen.get_height(); + #endif //allow some window movement from the screen borders //(some panels moves the window after it was realized) int dx = this.panel_sz - this.back_x; if (dx > 0) this.back_sz_x += dx; - dx = this.panel_sz - (screenx - this.back_x - this.back_sz_x +1); + dx = this.panel_sz - (monitor_x - this.back_x - this.back_sz_x +1); if (dx > 0) { this.back_sz_x += dx; this.back_x -= dx; @@ -243,7 +272,7 @@ public class PieWindow : Gtk.Window { int dy = this.panel_sz - this.back_y; if (dy > 0) this.back_sz_y += dy; - dy = this.panel_sz - (screeny - this.back_y - this.back_sz_y +1); + dy = this.panel_sz - (monitor_y - this.back_y - this.back_sz_y +1); if (dy > 0) { this.back_sz_y += dy; this.back_y -= dy; @@ -264,10 +293,10 @@ public class PieWindow : Gtk.Window { this.back_sz_y += this.back_y; this.back_y = 0; } - if (this.back_x + this.back_sz_x > screenx) - this.back_sz_x = screenx - this.back_x; - if (this.back_y + this.back_sz_y > screeny) - this.back_sz_y = screeny - this.back_y; + if (this.back_x + this.back_sz_x > monitor_x) + this.back_sz_x = monitor_x - this.back_x; + if (this.back_y + this.back_sz_y > monitor_y) + this.back_sz_y = monitor_y - this.back_y; this.background = new Image.capture_screen(this.back_x, this.back_y, this.back_sz_x, this.back_sz_y); } @@ -314,20 +343,27 @@ public class PieWindow : Gtk.Window { ///////////////////////////////////////////////////////////////////// private void get_mouse_position(out int mx, out int my) { - // get the mouse position - mx = 0; - my = 0; - Gdk.ModifierType mask; - - 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) { - this.get_window().get_device_position(device, out mx, out my, out mask); + #if HAVE_GTK_3_20 + var seat = Gdk.Display.get_default().get_default_seat(); + seat.get_pointer().get_position(null, out mx, out my); + #else + double x = 0.0; + double y = 0.0; + + 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) { + Gdk.Screen screen; + device.get_position( out screen, out x, out y ); + } } - } + + mx = (int) x; + my = (int) y; + #endif } ///////////////////////////////////////////////////////////////////// @@ -335,14 +371,19 @@ public class PieWindow : Gtk.Window { ///////////////////////////////////////////////////////////////////// private void set_mouse_position(int mx, int my) { - 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) { - device.warp(Gdk.Screen.get_default(), mx, my); + #if HAVE_GTK_3_20 + var seat = Gdk.Display.get_default().get_default_seat(); + seat.get_pointer().warp(this.screen, mx, my); + #else + 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) { + device.warp(Gdk.Screen.get_default(), mx, my); + } } - } + #endif } ///////////////////////////////////////////////////////////////////// @@ -350,6 +391,9 @@ public class PieWindow : Gtk.Window { ///////////////////////////////////////////////////////////////////// private bool draw_window(Cairo.Context ctx) { + int x, y; + this.get_position(out x, out y); + // paint the background image if there is no compositing if (this.has_compositing) { ctx.set_operator (Cairo.Operator.CLEAR); @@ -358,8 +402,6 @@ public class PieWindow : Gtk.Window { } else { //correct the background position if the window was moved //since the background image was captured - int x, y; - this.get_position(out x, out y); int dx = this.back_x - x; int dy = this.back_y - y; ctx.save(); @@ -370,9 +412,6 @@ public class PieWindow : Gtk.Window { ctx.restore(); } - // align the context to the center of the PieWindow - ctx.translate(this.renderer.center_x, this.renderer.center_y); - // get the mouse position int mouse_x, mouse_y; get_mouse_position( out mouse_x, out mouse_y ); @@ -381,9 +420,31 @@ public class PieWindow : Gtk.Window { double frame_time = this.timer.elapsed(); this.timer.reset(); + int center_x = this.renderer.center_x; + int center_y = this.renderer.center_y; + + // on wayland we have a fullscreen window and since we + // do not get the pointer location until the mouse moved + // we can only display the pie centered... + if (this.wayland) { + #if HAVE_GTK_3_22 + var monitor = Gdk.Display.get_default().get_monitor_at_point(mouse_x, mouse_y).get_geometry(); + center_x = monitor.width / 2; + center_y = monitor.height / 2; + #else + var screen = Gdk.Screen.get_default().get_root_window(); + center_x = screen.get_width() / 2; + center_y = screen.get_height() / 2; + #endif + } + + // align the context to the center of the PieWindow + x += center_x; + y += center_y; + ctx.translate(center_x, center_y); + // render the Pie - this.renderer.draw(frame_time, ctx, mouse_x - (int)this.renderer.center_x, - mouse_y - (int)this.renderer.center_y); + this.renderer.draw(frame_time, ctx, mouse_x - x, mouse_y - y); return true; } @@ -396,7 +457,6 @@ public class PieWindow : Gtk.Window { if (!this.closing) { this.closing = true; this.on_closing(); - Gtk.grab_remove(this); FocusGrabber.ungrab(); GLib.Timeout.add(10, () => { @@ -421,7 +481,6 @@ public class PieWindow : Gtk.Window { if (!this.closing) { this.closing = true; this.on_closing(); - Gtk.grab_remove(this); FocusGrabber.ungrab(); this.renderer.cancel(); diff --git a/src/renderers/sliceRenderer.vala b/src/renderers/sliceRenderer.vala index b465bd7..c370b10 100644 --- a/src/renderers/sliceRenderer.vala +++ b/src/renderers/sliceRenderer.vala @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// Copyright (c) 2011-2016 by Simon Schneegans +// Copyright (c) 2011-2017 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 diff --git a/src/themes/centerLayer.vala b/src/themes/centerLayer.vala index c4adbb8..8bd61e2 100644 --- a/src/themes/centerLayer.vala +++ b/src/themes/centerLayer.vala @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// Copyright (c) 2011-2016 by Simon Schneegans +// Copyright (c) 2011-2017 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 diff --git a/src/themes/sliceLayer.vala b/src/themes/sliceLayer.vala index 1a2c7cd..be196dd 100644 --- a/src/themes/sliceLayer.vala +++ b/src/themes/sliceLayer.vala @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// Copyright (c) 2011-2016 by Simon Schneegans +// Copyright (c) 2011-2017 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 diff --git a/src/themes/theme.vala b/src/themes/theme.vala index 9c1ac5c..4a1806d 100644 --- a/src/themes/theme.vala +++ b/src/themes/theme.vala @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// Copyright (c) 2011-2016 by Simon Schneegans +// Copyright (c) 2011-2017 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 diff --git a/src/themes/themeImporter.vala b/src/themes/themeImporter.vala index 24db741..5a373a6 100644 --- a/src/themes/themeImporter.vala +++ b/src/themes/themeImporter.vala @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// Copyright (c) 2011-2016 by Simon Schneegans +// Copyright (c) 2011-2017 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 diff --git a/src/utilities/animatedValue.vala b/src/utilities/animatedValue.vala index 5bb46f5..3dc0685 100644 --- a/src/utilities/animatedValue.vala +++ b/src/utilities/animatedValue.vala @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// Copyright (c) 2011-2016 by Simon Schneegans +// Copyright (c) 2011-2017 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 diff --git a/src/utilities/archiveReader.vala b/src/utilities/archiveReader.vala index 14183ac..df248cf 100644 --- a/src/utilities/archiveReader.vala +++ b/src/utilities/archiveReader.vala @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// Copyright (c) 2011-2016 by Simon Schneegans +// Copyright (c) 2011-2017 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 diff --git a/src/utilities/archiveWriter.vala b/src/utilities/archiveWriter.vala index b74b5d0..2a18154 100644 --- a/src/utilities/archiveWriter.vala +++ b/src/utilities/archiveWriter.vala @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// Copyright (c) 2011-2016 by Simon Schneegans +// Copyright (c) 2011-2017 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 diff --git a/src/utilities/bindingManager.vala b/src/utilities/bindingManager.vala index a21c0a1..82b6334 100644 --- a/src/utilities/bindingManager.vala +++ b/src/utilities/bindingManager.vala @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// Copyright (c) 2011-2016 by Simon Schneegans +// Copyright (c) 2011-2017 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 @@ -73,6 +73,12 @@ public class BindingManager : GLib.Object { private Keybinding? delayed_binding = null; ///////////////////////////////////////////////////////////////////// + /// Used to identify wayland sessions. + ///////////////////////////////////////////////////////////////////// + + private bool wayland = GLib.Environment.get_variable("XDG_SESSION_TYPE") == "wayland"; + + ///////////////////////////////////////////////////////////////////// /// Helper class to store keybinding ///////////////////////////////////////////////////////////////////// @@ -104,7 +110,9 @@ public class BindingManager : GLib.Object { ///////////////////////////////////////////////////////////////////// public void bind(Trigger trigger, string id) { - if (trigger.key_code != 0) { + + // global key grabbing is impossible on wayland + if (!wayland && trigger.key_code != 0) { unowned X.Display display = Gdk.X11.get_default_xdisplay(); X.ID xid = Gdk.X11.get_default_root_xwindow(); @@ -143,8 +151,8 @@ public class BindingManager : GLib.Object { public void unbind(string id) { foreach (var binding in bindings) { if (id == binding.id) { - if (binding.trigger.key_code == 0) { - //no key_code: just remove the bindind from the list + if (binding.trigger.key_code == 0 || wayland) { + //no key_code or wayland: just remove the bindind from the list bindings.remove(binding); return; } diff --git a/src/utilities/color.vala b/src/utilities/color.vala index 1e2baf3..cc65434 100644 --- a/src/utilities/color.vala +++ b/src/utilities/color.vala @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// Copyright (c) 2011-2016 by Simon Schneegans +// Copyright (c) 2011-2017 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 @@ -41,7 +41,7 @@ public class Color: GLib.Object { ///////////////////////////////////////////////////////////////////// public Color() { - Color.from_rgb(1.0f, 1.0f, 1.0f); + this.from_rgb(1.0f, 1.0f, 1.0f); } ///////////////////////////////////////////////////////////////////// @@ -49,7 +49,7 @@ public class Color: GLib.Object { ///////////////////////////////////////////////////////////////////// public Color.from_rgb(float red, float green, float blue) { - Color.from_rgba(red, green, blue, 1.0f); + this.from_rgba(red, green, blue, 1.0f); } ///////////////////////////////////////////////////////////////////// @@ -68,7 +68,7 @@ public class Color: GLib.Object { ///////////////////////////////////////////////////////////////////// public Color.from_gdk(Gdk.RGBA color) { - Color.from_rgba( + this.from_rgba( (float)color.red, (float)color.green, (float)color.blue, @@ -86,7 +86,7 @@ public class Color: GLib.Object { if (!ctx.lookup_color(style_name, out color)) { warning("Failed to get style color for widget style \"" + style_name + "\"!"); } - Color.from_gdk(color); + this.from_gdk(color); } ///////////////////////////////////////////////////////////////////// @@ -96,7 +96,7 @@ public class Color: GLib.Object { public Color.from_string(string hex_string) { var color = Gdk.RGBA(); color.parse(hex_string); - Color.from_gdk(color); + this.from_gdk(color); } ///////////////////////////////////////////////////////////////////// @@ -134,7 +134,7 @@ public class Color: GLib.Object { } } - Color.from_rgb((float)(rtotal/total), (float)(gtotal/total), (float)(btotal/total)); + this.from_rgb((float)(rtotal/total), (float)(gtotal/total), (float)(btotal/total)); if (s > 0.15f) s = 0.65f; diff --git a/src/utilities/config.vala b/src/utilities/config.vala index 3fc8d3f..1d3fde4 100644 --- a/src/utilities/config.vala +++ b/src/utilities/config.vala @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// Copyright (c) 2011-2016 by Simon Schneegans +// Copyright (c) 2011-2017 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 diff --git a/src/utilities/focusGrabber.vala b/src/utilities/focusGrabber.vala index 4a3212f..8424f12 100644 --- a/src/utilities/focusGrabber.vala +++ b/src/utilities/focusGrabber.vala @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// Copyright (c) 2011-2016 by Simon Schneegans +// Copyright (c) 2011-2017 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 @@ -28,18 +28,16 @@ public class FocusGrabber : GLib.Object { /// 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); - }); - } + public static void grab(Gdk.Window window) { + window.raise(); + window.focus(Gdk.CURRENT_TIME); + + if (!try_grab_window(window)) { + int i = 0; + Timeout.add(100, () => { + if (++i >= 100) return false; + return !try_grab_window(window); + }); } } @@ -47,50 +45,65 @@ public class FocusGrabber : GLib.Object { /// 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); + public static void ungrab() { + #if HAVE_GTK_3_20 + var seat = Gdk.Display.get_default().get_default_seat(); + seat.ungrab(); + #else + var display = Gdk.Display.get_default(); + var manager = display.get_device_manager(); - foreach(var device in list) { - if ((device.input_source == Gdk.InputSource.KEYBOARD && keyboard) - || (device.input_source != Gdk.InputSource.KEYBOARD && pointer)) + GLib.List<weak Gdk.Device?> list = manager.list_devices(Gdk.DeviceType.MASTER); + foreach(var device in list) { device.ungrab(Gdk.CURRENT_TIME); - } + } + #endif } ///////////////////////////////////////////////////////////////////// /// 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(); + private static bool try_grab_window(Gdk.Window window) { + #if HAVE_GTK_3_20 + // try again if window is not yet viewable + if (!window.is_viewable()) return false; - bool grabbed_all = true; + var seat = Gdk.Display.get_default().get_default_seat(); + var caps = Gdk.SeatCapabilities.POINTER | Gdk.SeatCapabilities.KEYBOARD; + var result = seat.grab(window, caps, true, null, null, null); - GLib.List<weak Gdk.Device?> list = manager.list_devices(Gdk.DeviceType.MASTER); + // for some reason GDK hides the window if the grab fails... + if (result != Gdk.GrabStatus.SUCCESS) { + window.show(); + } + + // continue trying to grab if it failed! + return result == Gdk.GrabStatus.SUCCESS; + #else + var display = Gdk.Display.get_default(); + var manager = display.get_device_manager(); - foreach(var device in list) { - if ((device.input_source == Gdk.InputSource.KEYBOARD && keyboard) - || (device.input_source != Gdk.InputSource.KEYBOARD && pointer)) { + bool grabbed_all = true; - var status = device.grab(window, Gdk.GrabOwnership.APPLICATION, owner_events, + GLib.List<weak Gdk.Device?> list = manager.list_devices(Gdk.DeviceType.MASTER); + + foreach(var device in list) { + var status = device.grab(window, Gdk.GrabOwnership.APPLICATION, true, Gdk.EventMask.ALL_EVENTS_MASK, null, Gdk.CURRENT_TIME); if (status != Gdk.GrabStatus.SUCCESS) grabbed_all = false; } - } - if (grabbed_all) - return true; + if (grabbed_all) + return true; - ungrab(keyboard, pointer); + ungrab(); - return false; + return false; + #endif } } diff --git a/src/utilities/key.vala b/src/utilities/key.vala index 432c40e..93e18b5 100644 --- a/src/utilities/key.vala +++ b/src/utilities/key.vala @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// Copyright (c) 2011-2016 by Simon Schneegans +// Copyright (c) 2011-2017 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 diff --git a/src/utilities/logger.vala b/src/utilities/logger.vala index ecc551e..48f27c6 100644 --- a/src/utilities/logger.vala +++ b/src/utilities/logger.vala @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// Copyright (c) 2011-2016 by Simon Schneegans +// Copyright (c) 2011-2017 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 @@ -29,33 +29,33 @@ public class Logger { /// If these are set to false, the according messages are not shown ///////////////////////////////////////////////////////////////////// - private static const bool display_debug = true; - private static const bool display_warning = true; - private static const bool display_error = true; - private static const bool display_message = true; + private const bool display_debug = true; + private const bool display_warning = true; + private const bool display_error = true; + private const bool display_message = true; ///////////////////////////////////////////////////////////////////// /// If these are set to false, the according messages are not logged ///////////////////////////////////////////////////////////////////// - private static const bool log_debug = false; - private static const bool log_warning = true; - private static const bool log_error = true; - private static const bool log_message = true; + private const bool log_debug = false; + private const bool log_warning = true; + private const bool log_error = true; + private const bool log_message = true; ///////////////////////////////////////////////////////////////////// /// If true, a time stamp is shown in each message. ///////////////////////////////////////////////////////////////////// - private static const bool display_time = false; - private static const bool log_time = true; + private const bool display_time = false; + private const bool log_time = true; ///////////////////////////////////////////////////////////////////// /// If true, the origin of the message is shown. In form file:line ///////////////////////////////////////////////////////////////////// - private static const bool display_file = false; - private static const bool log_file = false; + private const bool display_file = false; + private const bool log_file = false; ///////////////////////////////////////////////////////////////////// /// A regex, used to format the standard message. @@ -67,7 +67,7 @@ public class Logger { /// Limit log and statistics size to roughly 1 MB. ///////////////////////////////////////////////////////////////////// - private static const int max_log_length = 1000000; + private const int max_log_length = 1000000; private static int log_length; diff --git a/src/utilities/paths.vala b/src/utilities/paths.vala index 68c5384..f076ddc 100644 --- a/src/utilities/paths.vala +++ b/src/utilities/paths.vala @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// Copyright (c) 2011-2016 by Simon Schneegans +// Copyright (c) 2011-2017 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 @@ -150,9 +150,7 @@ public class Paths : GLib.Object { Gtk.IconTheme.get_default().append_search_path(path); } - Gtk.IconTheme.get_default().append_search_path("/usr/share/pixmaps/"); - Gtk.IconTheme.get_default().append_search_path("/usr/share/icons/hicolor/scalable/apps"); - Gtk.IconTheme.get_default().append_search_path("/usr/local/share/icons/hicolor/scalable/apps"); + Gtk.IconTheme.get_default().append_search_path(GLib.Environment.get_home_dir() + ".icons"); // get global paths var default_dir = GLib.File.new_for_path("/usr/share/gnome-pie/"); diff --git a/src/utilities/trigger.vala b/src/utilities/trigger.vala index aeed3fb..ac236cd 100644 --- a/src/utilities/trigger.vala +++ b/src/utilities/trigger.vala @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////// -// Copyright (c) 2011-2016 by Simon Schneegans +// Copyright (c) 2011-2017 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 |