aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarco Trevisan (TreviƱo) <mail@3v1n0.net>2013-04-05 14:43:22 +0000
committerTarmac <Unknown>2013-04-05 14:43:22 +0000
commitd774ac38dd84f52394bfcbb557b0e3475f999f34 (patch)
treeecfa17ebc292904664ce58e5ecb5905744518bbb
parenta83c4b7d257344bff272c169e36736a2205fda31 (diff)
parent0762482ba33dc83ce4675481895bf0cd6568e53d (diff)
downloadayatana-indicator-sound-d774ac38dd84f52394bfcbb557b0e3475f999f34.tar.gz
ayatana-indicator-sound-d774ac38dd84f52394bfcbb557b0e3475f999f34.tar.bz2
ayatana-indicator-sound-d774ac38dd84f52394bfcbb557b0e3475f999f34.zip
PlayerActivator: Use BAMF to find the windows to activate with timestamp
Improved the"old" GtkApplicationPlayer, using BAMF as a fallback method to activate an application's windows. Basically we try to get the windows of the selected application and when found we focus them using the activation timestamp. Fixes: https://bugs.launchpad.net/bugs/627195. Approved by PS Jenkins bot, Lars Uebernickel.
-rw-r--r--configure.ac2
-rw-r--r--debian/control1
-rw-r--r--src/Makefile.am4
-rw-r--r--src/metadata-menu-item.vala2
-rw-r--r--src/player-activator.vala (renamed from src/gtk-application-player.vala)102
-rw-r--r--src/player-controller.vala4
6 files changed, 98 insertions, 17 deletions
diff --git a/configure.ac b/configure.ac
index 7d8c008..3a72c5c 100644
--- a/configure.ac
+++ b/configure.ac
@@ -52,7 +52,9 @@ PKG_CHECK_MODULES(APPLET, gtk+-3.0 >= $GTK_REQUIRED_VERSION
PKG_CHECK_MODULES(SOUNDSERVICE, dbusmenu-glib-0.4 >= $DBUSMENUGLIB_REQUIRED_VERSION
indicator3-0.4
gee-1.0
+ gdk-x11-3.0
gio-unix-2.0
+ libbamf3
libxml-2.0)
AC_SUBST(APPLET_CFLAGS)
diff --git a/debian/control b/debian/control
index 320f8b7..abd1f75 100644
--- a/debian/control
+++ b/debian/control
@@ -10,6 +10,7 @@ Build-Depends: debhelper (>= 9.0),
gnome-common,
autotools-dev,
valac-0.18,
+ libbamf3-dev,
libglib2.0-dev (>= 2.22.3),
libgtk-3-dev,
libdbusmenu-glib-dev (>= 0.5.90),
diff --git a/src/Makefile.am b/src/Makefile.am
index 381da56..55df0f6 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -68,7 +68,7 @@ music_bridge_VALASOURCES = \
playlists-menu-item.vala \
freedesktop-interfaces.vala \
fetch-file.vala \
- gtk-application-player.vala
+ player-activator.vala
music_bridge_VALAFLAGS = \
--ccode \
@@ -83,7 +83,9 @@ music_bridge_VALAFLAGS = \
--pkg gio-2.0 \
--pkg gio-unix-2.0 \
--pkg gdk-3.0 \
+ --pkg gdk-x11-3.0 \
--pkg gdk-pixbuf-2.0 \
+ --pkg libbamf3 \
--pkg libxml-2.0
$(MAINTAINER_VALAFLAGS)
diff --git a/src/metadata-menu-item.vala b/src/metadata-menu-item.vala
index a81c143..f4a7e68 100644
--- a/src/metadata-menu-item.vala
+++ b/src/metadata-menu-item.vala
@@ -177,7 +177,7 @@ public class MetadataMenuitem : PlayerItem
this.owner.instantiate(timestamp);
}
else if (this.owner.current_state == PlayerController.state.CONNECTED) {
- this.owner.gtk_app_player.activate(timestamp);
+ this.owner.player_activator.activate(timestamp);
this.owner.mpris_bridge.expose(timestamp);
}
}
diff --git a/src/gtk-application-player.vala b/src/player-activator.vala
index 8422ca5..7437a35 100644
--- a/src/gtk-application-player.vala
+++ b/src/player-activator.vala
@@ -4,16 +4,16 @@ Copyright 2013 Canonical Ltd.
Authors:
Marco Trevisan <marco.trevisan@canonical.com>
-This program is free software: you can redistribute it and/or modify it
-under the terms of the GNU General Public License version 3, as published
+This program is free software: you can redistribute it and/or modify it
+under the terms of the GNU General Public License version 3, as published
by the Free Software Foundation.
-This program is distributed in the hope that it will be useful, but
-WITHOUT ANY WARRANTY; without even the implied warranties of
-MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
+This program is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranties of
+MERCHANTABILITY, SATISFACTORY QUALITY, 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
+You should have received a copy of the GNU General Public License along
with this program. If not, see <http://www.gnu.org/licenses/>.
*/
@@ -22,24 +22,44 @@ public interface DBusGtkApplication : Object {
public abstract void Activate(GLib.HashTable<string, Variant?> platform_data) throws IOError;
}
-public class GtkApplicationPlayer : GLib.Object
+public class PlayerActivator : GLib.Object
{
public PlayerController owner {get; construct;}
private bool gtk_application_searched = false;
private DBusGtkApplication gtk_application;
+ private Bamf.Application bamf_application;
- public GtkApplicationPlayer(PlayerController ctrl)
+ private const uint MAX_BAMF_APPLICATION_WAIT_MS = 1000;
+ private int64 last_check_time;
+
+ public PlayerActivator(PlayerController ctrl)
{
GLib.Object(owner: ctrl);
}
public void activate(uint timestamp)
{
+ if (!activate_gtk_appplication(timestamp)) {
+ if (!activate_bamf_appplication(timestamp)) {
+ // Let's wait BAMF to update its windows list
+ this.last_check_time = get_monotonic_time();
+
+ Idle.add(() => {
+ bool activated = activate_bamf_appplication(timestamp);
+ int64 waited = (get_monotonic_time() - this.last_check_time) / 1000;
+ return !activated && waited < MAX_BAMF_APPLICATION_WAIT_MS;
+ });
+ }
+ }
+ }
+
+ private bool activate_gtk_appplication(uint timestamp)
+ {
this.setup_gtk_application();
if (this.gtk_application == null) {
- return;
+ return false;
}
var context = Gdk.Display.get_default().get_app_launch_context();
@@ -49,9 +69,13 @@ public class GtkApplicationPlayer : GLib.Object
data["desktop-startup-id"] = context.get_startup_notify_id(this.owner.app_info, new GLib.List<GLib.File>());
try {
- this.gtk_application.Activate(data);
+ this.gtk_application.Activate(data);
}
- catch (IOError e) {}
+ catch (IOError e) {
+ return false;
+ }
+
+ return true;
}
private void setup_gtk_application()
@@ -79,7 +103,7 @@ public class GtkApplicationPlayer : GLib.Object
private void find_iface_path(DBusConnection connection, string name, string path, string target_iface, out string found_path)
{
- found_path = null;
+ found_path = null;
DBusNodeInfo node = null;
try {
@@ -120,4 +144,56 @@ public class GtkApplicationPlayer : GLib.Object
}
}
}
-} \ No newline at end of file
+
+ private void setup_bamf_application()
+ {
+ this.bamf_application = null;
+ var desktop_app = this.owner.app_info as DesktopAppInfo;
+
+ if (desktop_app == null)
+ return;
+
+ foreach (var app in Bamf.Matcher.get_default().get_applications()) {
+ if (app.get_desktop_file() == desktop_app.get_filename()) {
+ this.bamf_application = app;
+ break;
+ }
+ }
+ }
+
+ private bool activate_bamf_appplication(uint timestamp)
+ {
+ this.setup_bamf_application();
+
+ if (this.bamf_application == null)
+ return false;
+
+ bool focused = false;
+ var dpy = Gdk.Display.get_default();
+
+ foreach (var win in this.bamf_application.get_windows()) {
+ X.Window xid = 0;
+
+ if (win is Bamf.Window) {
+ if (win.get_window_type() != Bamf.WindowType.NORMAL)
+ continue;
+
+ xid = win.get_xid();
+ }
+ else if (win is Bamf.Tab) {
+ xid = (X.Window) (win as Bamf.Tab).get_xid();
+ }
+
+ if (xid > 0) {
+ var xwin = Gdk.X11Window.foreign_new_for_display(dpy, xid);
+
+ if (xwin != null) {
+ xwin.focus(timestamp);
+ focused = true;
+ }
+ }
+ }
+
+ return focused;
+ }
+}
diff --git a/src/player-controller.vala b/src/player-controller.vala
index dbe7c3c..8c3339e 100644
--- a/src/player-controller.vala
+++ b/src/player-controller.vala
@@ -45,7 +45,7 @@ public class PlayerController : GLib.Object
public string dbus_name { get; set;}
public ArrayList<PlayerItem> custom_items;
public Mpris2Controller mpris_bridge;
- public GtkApplicationPlayer gtk_app_player;
+ public PlayerActivator player_activator;
public AppInfo? app_info { get; set;}
public int menu_offset { get; set;}
public string icon_name { get; set; }
@@ -150,7 +150,7 @@ public class PlayerController : GLib.Object
debug ( " establish mpris connection - use playlists value = %s ",
this.use_playlists.to_string() );
this.mpris_bridge = new Mpris2Controller (this);
- this.gtk_app_player = new GtkApplicationPlayer (this);
+ this.player_activator = new PlayerActivator (this);
this.determine_state ();
}