From 309d161f6d464fcea2de200bb3cb5a7cb784b6d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Frings-F=C3=BCrst?= Date: Mon, 24 Jul 2017 19:58:27 +0200 Subject: New upstream version 0.7.1 --- src/actionGroups/actionGroup.vala | 2 +- src/actionGroups/bookmarkGroup.vala | 93 ++++++++-------- src/actionGroups/clipboardGroup.vala | 4 +- src/actionGroups/devicesGroup.vala | 5 +- src/actionGroups/groupRegistry.vala | 42 +++++--- src/actionGroups/menuGroup.vala | 5 +- src/actionGroups/sessionGroup.vala | 2 +- src/actionGroups/windowListGroup.vala | 198 +++++++++++++++++++--------------- 8 files changed, 195 insertions(+), 156 deletions(-) (limited to 'src/actionGroups') 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,20 +63,43 @@ 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); } } } + ///////////////////////////////////////////////////////////////////// + /// 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 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(); - construct { - this.screen = Wnck.Screen.get_default(); + Gtk.IconTheme.get_default().changed.connect(() => { + WindowListGroup.cached_icon_name = new Gee.HashMap(); + 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 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; + } } } -- cgit v1.2.3