summaryrefslogtreecommitdiff
path: root/src/actionGroups
diff options
context:
space:
mode:
Diffstat (limited to 'src/actionGroups')
-rw-r--r--src/actionGroups/actionGroup.vala23
-rw-r--r--src/actionGroups/clipboardGroup.vala124
-rw-r--r--src/actionGroups/groupRegistry.vala31
-rw-r--r--src/actionGroups/windowListGroup.vala54
-rw-r--r--src/actionGroups/workspaceWindowListGroup.vala145
5 files changed, 183 insertions, 194 deletions
diff --git a/src/actionGroups/actionGroup.vala b/src/actionGroups/actionGroup.vala
index 8bbcde4..85488ad 100644
--- a/src/actionGroups/actionGroup.vala
+++ b/src/actionGroups/actionGroup.vala
@@ -56,6 +56,20 @@ public class ActionGroup : GLib.Object {
public virtual void on_remove() {}
/////////////////////////////////////////////////////////////////////
+ /// This one is called, when the ActionGroup is saved.
+ /////////////////////////////////////////////////////////////////////
+
+ public virtual void on_save(Xml.TextWriter writer) {
+ writer.write_attribute("type", GroupRegistry.descriptions[this.get_type().name()].id);
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// This one is called, when the ActionGroup is loaded.
+ /////////////////////////////////////////////////////////////////////
+
+ public virtual void on_load(Xml.Node* data) {}
+
+ /////////////////////////////////////////////////////////////////////
/// Adds a new Action to the group.
/////////////////////////////////////////////////////////////////////
@@ -76,8 +90,9 @@ public class ActionGroup : GLib.Object {
/////////////////////////////////////////////////////////////////////
public void disable_quickactions() {
- foreach (var action in actions)
+ foreach (var action in actions) {
action.is_quickaction = false;
+ }
}
/////////////////////////////////////////////////////////////////////
@@ -85,9 +100,11 @@ public class ActionGroup : GLib.Object {
/////////////////////////////////////////////////////////////////////
public bool has_quickaction() {
- foreach (var action in actions)
- if (action.is_quickaction)
+ foreach (var action in actions) {
+ if (action.is_quickaction) {
return true;
+ }
+ }
return false;
}
diff --git a/src/actionGroups/clipboardGroup.vala b/src/actionGroups/clipboardGroup.vala
index ad18740..58409de 100644
--- a/src/actionGroups/clipboardGroup.vala
+++ b/src/actionGroups/clipboardGroup.vala
@@ -25,34 +25,78 @@ namespace GnomePie {
public class ClipboardGroup : ActionGroup {
/////////////////////////////////////////////////////////////////////
- ///
- /////////////////////////////////////////////////////////////////////
private class ClipboardItem : GLib.Object {
- public string name { get; private set; }
- public string icon { get; private set; }
+ public string name { get; protected set; }
+ public string icon { get; protected set; }
+
+ protected Gtk.Clipboard clipboard { get; set; }
+ protected static Key paste_key = new Key.from_string("<Control>v");
+
+ public virtual void paste() {}
+ }
- private Gtk.SelectionData contents;
+ /////////////////////////////////////////////////////////////////////
- public ClipboardItem(Gtk.SelectionData contents) {
- this.contents = contents.copy();
- this.name = this.contents.get_text() ?? "";
- this.icon = "edit-paste";
+ private class TextClipboardItem : ClipboardItem {
+
+ public TextClipboardItem(Gtk.Clipboard clipboard) {
+ GLib.Object(clipboard : clipboard,
+ name : clipboard.wait_for_text(),
+ icon : "edit-paste");
+
+ // check whether a file has been copied and search for a cool icon
+ var first_line = this.name.substring(0, this.name.index_of("\n"));
+ var file = GLib.File.new_for_path(first_line);
+
+ if (file.query_exists()) {
+ try {
+ var info = file.query_info("standard::icon", 0);
+ this.icon = Icon.get_icon_name(info.get_icon());
+ } catch (Error e) {
+ warning("Failed to generate icon for ClipboardGroupItem.");
+ }
+ }
}
- public void paste() {
- debug(name);
+ public override void paste() {
+ clipboard.set_text(name, name.length);
+ paste_key.press();
}
}
- public ClipboardGroup(string parent_id) {
- GLib.Object(parent_id : parent_id);
+ /////////////////////////////////////////////////////////////////////
+
+ private class ImageClipboardItem : ClipboardItem {
+
+ private Gdk.Pixbuf image { get; set; }
+
+ public ImageClipboardItem(Gtk.Clipboard clipboard) {
+ GLib.Object(clipboard : clipboard,
+ name : _("Image data"),
+ icon : "image-viewer");
+ this.image = clipboard.wait_for_image();
+ }
+
+ public override void paste() {
+ clipboard.set_image(image);
+ paste_key.press();
+ }
}
/////////////////////////////////////////////////////////////////////
+ /// The maximum remembered items of the clipboard.
+ /////////////////////////////////////////////////////////////////////
+
+ public int max_items {get; set; default=8; }
+
/////////////////////////////////////////////////////////////////////
+ public ClipboardGroup(string parent_id) {
+ GLib.Object(parent_id : parent_id);
+ }
+
/////////////////////////////////////////////////////////////////////
/// Used to register this type of ActionGroup. It sets the display
/// name for this ActionGroup, it's icon name and the string used in
@@ -74,12 +118,7 @@ public class ClipboardGroup : ActionGroup {
private Gtk.Clipboard clipboard;
-
- /////////////////////////////////////////////////////////////////////
- /// The maximum remembered items of the clipboard.
- /////////////////////////////////////////////////////////////////////
-
- private static const int max_items = 6;
+ private bool ignore_next_change = false;
private Gee.ArrayList<ClipboardItem?> items;
@@ -89,26 +128,61 @@ public class ClipboardGroup : ActionGroup {
this.clipboard.owner_change.connect(this.on_change);
}
+ /////////////////////////////////////////////////////////////////////
+ /// This one is called, when the ActionGroup is saved.
+ /////////////////////////////////////////////////////////////////////
+
+ public override void on_save(Xml.TextWriter writer) {
+ base.on_save(writer);
+ writer.write_attribute("max_items", this.max_items.to_string());
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// This one is called, when the ActionGroup is loaded.
+ /////////////////////////////////////////////////////////////////////
+
+ public override void on_load(Xml.Node* data) {
+ for (Xml.Attr* attribute = data->properties; attribute != null; attribute = attribute->next) {
+ string attr_name = attribute->name.down();
+ string attr_content = attribute->children->content;
+
+ if (attr_name == "max_items") {
+ this.max_items = int.parse(attr_content);
+ }
+ }
+ }
+
private void on_change() {
+ if (ignore_next_change) {
+ ignore_next_change = false;
+ return;
+ }
+
if (this.clipboard.wait_is_text_available()) {
- this.clipboard.request_contents(Gdk.Atom.intern("text/plain", false), this.add_item);
+ if (clipboard.wait_for_text() != null) {
+ add_item(new TextClipboardItem(this.clipboard));
+ }
+ } else if (this.clipboard.wait_is_image_available()) {
+ add_item(new ImageClipboardItem(this.clipboard));
}
}
- private void add_item(Gtk.Clipboard c, Gtk.SelectionData contents) {
- var new_item = new ClipboardItem(contents);
+ private void add_item(ClipboardItem item) {
- if (this.items.size == ClipboardGroup.max_items)
+ // remove one item if there are too many
+ if (this.items.size == this.max_items) {
this.items.remove_at(0);
+ }
- this.items.add(new_item);
+ this.items.add(item);
// update slices
this.delete_all();
- for (int i=0; i<this.items.size; ++i) {
+ for (int i=this.items.size-1; i>=0; --i) {
var action = new SigAction(items[i].name, items[i].icon, i.to_string());
action.activated.connect(() => {
+ ignore_next_change = true;
this.items[int.parse(action.real_command)].paste();
});
this.add_action(action);
diff --git a/src/actionGroups/groupRegistry.vala b/src/actionGroups/groupRegistry.vala
index ebf34ba..c97cf95 100644
--- a/src/actionGroups/groupRegistry.vala
+++ b/src/actionGroups/groupRegistry.vala
@@ -57,6 +57,10 @@ public class GroupRegistry : GLib.Object {
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);
+
type_description = DevicesGroup.register();
types.add(typeof(DevicesGroup).name());
descriptions.set(typeof(DevicesGroup).name(), type_description);
@@ -72,10 +76,6 @@ public class GroupRegistry : GLib.Object {
type_description = WindowListGroup.register();
types.add(typeof(WindowListGroup).name());
descriptions.set(typeof(WindowListGroup).name(), type_description);
-
- type_description = WorkspaceWindowListGroup.register();
- types.add(typeof(WorkspaceWindowListGroup).name());
- descriptions.set(typeof(WorkspaceWindowListGroup).name(), type_description);
}
/////////////////////////////////////////////////////////////////////
@@ -84,12 +84,23 @@ public class GroupRegistry : GLib.Object {
public static ActionGroup? create_group(string type_id, string parent_id) {
switch (type_id) {
- case "bookmarks": return new BookmarkGroup(parent_id);
- case "devices": return new DevicesGroup(parent_id);
- case "menu": return new MenuGroup(parent_id);
- case "session": return new SessionGroup(parent_id);
- case "window_list": return new WindowListGroup(parent_id);
- case "workspace_window_list": return new WorkspaceWindowListGroup(parent_id);
+ case "bookmarks":
+ return new BookmarkGroup(parent_id);
+ case "clipboard":
+ return new ClipboardGroup(parent_id);
+ case "devices":
+ return new DevicesGroup(parent_id);
+ case "menu":
+ return new MenuGroup(parent_id);
+ case "session":
+ return new SessionGroup(parent_id);
+ case "window_list":
+ return new WindowListGroup(parent_id);
+ // deprecated
+ case "workspace_window_list":
+ var group = new WindowListGroup(parent_id);
+ group.current_workspace_only = true;
+ return group;
}
return null;
diff --git a/src/actionGroups/windowListGroup.vala b/src/actionGroups/windowListGroup.vala
index 1560f5f..69029a7 100644
--- a/src/actionGroups/windowListGroup.vala
+++ b/src/actionGroups/windowListGroup.vala
@@ -38,6 +38,8 @@ public class WindowListGroup : ActionGroup {
return description;
}
+ public bool current_workspace_only { get; set; default=false; }
+
/////////////////////////////////////////////////////////////////////
/// Two members needed to avoid useless, frequent changes of the
/// stored Actions.
@@ -65,22 +67,50 @@ public class WindowListGroup : ActionGroup {
this.screen.window_opened.connect(reload);
this.screen.window_closed.connect(reload);
+ this.screen.active_workspace_changed.connect(reload);
- this.load();
+ this.update();
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// This one is called, when the ActionGroup is saved.
+ /////////////////////////////////////////////////////////////////////
+
+ public override void on_save(Xml.TextWriter writer) {
+ base.on_save(writer);
+ writer.write_attribute("current_workspace_only", this.current_workspace_only.to_string());
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ /// This one is called, when the ActionGroup is loaded.
+ /////////////////////////////////////////////////////////////////////
+
+ public override void on_load(Xml.Node* data) {
+ for (Xml.Attr* attribute = data->properties; attribute != null; attribute = attribute->next) {
+ string attr_name = attribute->name.down();
+ string attr_content = attribute->children->content;
+
+ if (attr_name == "current_workspace_only") {
+ this.current_workspace_only = bool.parse(attr_content);
+ }
+ }
}
/////////////////////////////////////////////////////////////////////
/// Loads all currently opened windows and creates actions for them.
/////////////////////////////////////////////////////////////////////
- private void load() {
+ private void update() {
unowned GLib.List<Wnck.Window?> windows = this.screen.get_windows();
var matcher = Bamf.Matcher.get_default();
foreach (var window in windows) {
if (window.get_window_type() == Wnck.WindowType.NORMAL
- && !window.is_skip_pager() && !window.is_skip_tasklist()) {
+ && !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 bamf_app = matcher.get_application_for_xid((uint32)window.get_xid());
@@ -102,17 +132,18 @@ public class WindowListGroup : ActionGroup {
if (win.get_workspace() != null) {
//select the workspace
- if (win.get_workspace() != win.get_screen().get_active_workspace())
+ if (win.get_workspace() != win.get_screen().get_active_workspace()) {
win.get_workspace().activate(time_stamp);
+ }
- //select the viewport inside the wprkspace
+ //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();
+ 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;
@@ -121,8 +152,9 @@ public class WindowListGroup : ActionGroup {
}
}
- if (win.is_minimized())
+ if (win.is_minimized()) {
win.unminimize(time_stamp);
+ }
win.activate_transient(time_stamp);
});
@@ -147,7 +179,7 @@ public class WindowListGroup : ActionGroup {
// reload
this.delete_all();
- this.load();
+ this.update();
this.changing = false;
return false;
diff --git a/src/actionGroups/workspaceWindowListGroup.vala b/src/actionGroups/workspaceWindowListGroup.vala
deleted file mode 100644
index 42a4863..0000000
--- a/src/actionGroups/workspaceWindowListGroup.vala
+++ /dev/null
@@ -1,145 +0,0 @@
-/////////////////////////////////////////////////////////////////////////
-// Copyright (c) 2011-2015 by Simon Schneegans
-//
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or (at
-// your option) any later version.
-//
-// This program is distributed in the hope that it will be useful, but
-// WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program. If not, see <http://www.gnu.org/licenses/>.
-/////////////////////////////////////////////////////////////////////////
-
-namespace GnomePie {
-
-/////////////////////////////////////////////////////////////////////
-/// This group displays a list of all running application windows of
-/// the current workspace.
-/////////////////////////////////////////////////////////////////////
-
-public class WorkspaceWindowListGroup : ActionGroup {
-
- /////////////////////////////////////////////////////////////////////
- /// Used to register this type of ActionGroup. It sets the display
- /// name for this ActionGroup, it's icon name and the string used in
- /// the pies.conf file for this kind of ActionGroups.
- /////////////////////////////////////////////////////////////////////
-
- public static GroupRegistry.TypeDescription register() {
- var description = new GroupRegistry.TypeDescription();
- description.name = _("Group: Window List for current workspace");
- description.icon = "preferences-system-windows";
- description.description = _("Shows a Slice for each of your opened windows on the current workspace.");
- description.id = "workspace_window_list";
- return description;
- }
-
- /////////////////////////////////////////////////////////////////////
- /// Two members needed to avoid useless, frequent changes of the
- /// stored Actions.
- /////////////////////////////////////////////////////////////////////
-
- private bool changing = false;
- private bool changed_again = false;
-
- private Wnck.Screen screen;
-
- /////////////////////////////////////////////////////////////////////
- /// C'tor, initializes all members.
- /////////////////////////////////////////////////////////////////////
-
- public WorkspaceWindowListGroup(string parent_id) {
- GLib.Object(parent_id : parent_id);
- }
-
- /////////////////////////////////////////////////////////////////////
- /// Loads all windows.
- /////////////////////////////////////////////////////////////////////
-
- construct {
- this.screen = Wnck.Screen.get_default();
-
- this.screen.window_opened.connect(reload);
- this.screen.window_closed.connect(reload);
- this.screen.active_workspace_changed.connect(reload);
-
- this.load();
- }
-
- /////////////////////////////////////////////////////////////////////
- /// Loads all currently opened windows and creates actions for them.
- /////////////////////////////////////////////////////////////////////
-
- private void load() {
- unowned GLib.List<Wnck.Window?> windows = this.screen.get_windows();
-
- var matcher = Bamf.Matcher.get_default();
-
- foreach (var window in windows) {
- if (window.get_window_type() == Wnck.WindowType.NORMAL
- && !window.is_skip_pager() && !window.is_skip_tasklist()
- && window.get_workspace() != null
- && window.get_workspace() == this.screen.get_active_workspace()) {
-
- var application = window.get_application();
- var bamf_app = matcher.get_application_for_xid((uint32)window.get_xid());
-
- string name = window.get_name();
-
- if (name.length > 30)
- name = name.substring(0, 30) + "...";
-
- var action = new SigAction(
- name,
- (bamf_app == null) ? application.get_icon_name().down() : bamf_app.get_icon(),
- "%lu".printf(window.get_xid())
- );
- action.activated.connect((time_stamp) => {
- Wnck.Screen.get_default().force_update();
-
- var xid = (X.Window)uint64.parse(action.real_command);
- var win = Wnck.Window.get(xid);
-
- if (win.is_minimized())
- win.unminimize(time_stamp);
-
- win.activate_transient(time_stamp);
- });
- this.add_action(action);
- }
- }
- }
-
- /////////////////////////////////////////////////////////////////////
- /// Reloads all running applications.
- /////////////////////////////////////////////////////////////////////
-
- 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;
- }
-
- // reload
- this.delete_all();
- this.load();
-
- this.changing = false;
- return false;
- });
- } else {
- this.changed_again = true;
- }
- }
-}
-
-}