~indicator-applet-developers/indicator-sound/trunk.13.04

« back to all changes in this revision

Viewing changes to src/player-activator.vala

  • Committer: Tarmac
  • Author(s): Marco Trevisan (Treviño)
  • Date: 2013-04-05 13:05:54 UTC
  • mfrom: (344.1.7 indicator-sound)
  • Revision ID: tarmac-20130405130554-9eawtnup17d6ioo2
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.

Show diffs side-by-side

added added

removed removed

Lines of Context:
4
4
Authors:
5
5
    Marco Trevisan <marco.trevisan@canonical.com>
6
6
 
7
 
This program is free software: you can redistribute it and/or modify it 
8
 
under the terms of the GNU General Public License version 3, as published 
 
7
This program is free software: you can redistribute it and/or modify it
 
8
under the terms of the GNU General Public License version 3, as published
9
9
by the Free Software Foundation.
10
10
 
11
 
This program is distributed in the hope that it will be useful, but 
12
 
WITHOUT ANY WARRANTY; without even the implied warranties of 
13
 
MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR 
 
11
This program is distributed in the hope that it will be useful, but
 
12
WITHOUT ANY WARRANTY; without even the implied warranties of
 
13
MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
14
14
PURPOSE.  See the GNU General Public License for more details.
15
15
 
16
 
You should have received a copy of the GNU General Public License along 
 
16
You should have received a copy of the GNU General Public License along
17
17
with this program.  If not, see <http://www.gnu.org/licenses/>.
18
18
*/
19
19
 
22
22
  public abstract void Activate(GLib.HashTable<string, Variant?> platform_data) throws IOError;
23
23
}
24
24
 
25
 
public class GtkApplicationPlayer : GLib.Object
 
25
public class PlayerActivator : GLib.Object
26
26
{
27
27
  public PlayerController owner {get; construct;}
28
28
 
29
29
  private bool gtk_application_searched = false;
30
30
  private DBusGtkApplication gtk_application;
31
 
 
32
 
  public GtkApplicationPlayer(PlayerController ctrl)
 
31
  private Bamf.Application bamf_application;
 
32
 
 
33
  private const uint MAX_BAMF_APPLICATION_WAIT_MS = 1000;
 
34
  private int64 last_check_time;
 
35
 
 
36
  public PlayerActivator(PlayerController ctrl)
33
37
  {
34
38
    GLib.Object(owner: ctrl);
35
39
  }
36
40
 
37
41
  public void activate(uint timestamp)
38
42
  {
 
43
    if (!activate_gtk_appplication(timestamp)) {
 
44
      if (!activate_bamf_appplication(timestamp)) {
 
45
        // Let's wait BAMF to update its windows list
 
46
        this.last_check_time = get_monotonic_time();
 
47
 
 
48
        Idle.add(() => {
 
49
          bool activated = activate_bamf_appplication(timestamp);
 
50
          int64 waited = (get_monotonic_time() - this.last_check_time) / 1000;
 
51
          return !activated && waited < MAX_BAMF_APPLICATION_WAIT_MS;
 
52
        });
 
53
      }
 
54
    }
 
55
  }
 
56
 
 
57
  private bool activate_gtk_appplication(uint timestamp)
 
58
  {
39
59
    this.setup_gtk_application();
40
60
 
41
61
    if (this.gtk_application == null) {
42
 
      return;
 
62
      return false;
43
63
    }
44
64
 
45
65
    var context = Gdk.Display.get_default().get_app_launch_context();
49
69
    data["desktop-startup-id"] = context.get_startup_notify_id(this.owner.app_info, new GLib.List<GLib.File>());
50
70
 
51
71
    try {
52
 
        this.gtk_application.Activate(data);
53
 
    }
54
 
    catch (IOError e) {}
 
72
      this.gtk_application.Activate(data);
 
73
    }
 
74
    catch (IOError e) {
 
75
      return false;
 
76
    }
 
77
 
 
78
    return true;
55
79
  }
56
80
 
57
81
  private void setup_gtk_application()
79
103
 
80
104
  private void find_iface_path(DBusConnection connection, string name, string path, string target_iface, out string found_path)
81
105
  {
82
 
        found_path = null;
 
106
    found_path = null;
83
107
    DBusNodeInfo node = null;
84
108
 
85
109
    try {
120
144
      }
121
145
    }
122
146
  }
123
 
}
 
 
b'\\ No newline at end of file'
 
147
 
 
148
  private void setup_bamf_application()
 
149
  {
 
150
    this.bamf_application = null;
 
151
    var desktop_app = this.owner.app_info as DesktopAppInfo;
 
152
 
 
153
    if (desktop_app == null)
 
154
      return;
 
155
 
 
156
    foreach (var app in Bamf.Matcher.get_default().get_applications()) {
 
157
      if (app.get_desktop_file() == desktop_app.get_filename()) {
 
158
        this.bamf_application = app;
 
159
        break;
 
160
      }
 
161
    }
 
162
  }
 
163
 
 
164
  private bool activate_bamf_appplication(uint timestamp)
 
165
  {
 
166
    this.setup_bamf_application();
 
167
 
 
168
    if (this.bamf_application == null)
 
169
      return false;
 
170
 
 
171
    bool focused = false;
 
172
    var dpy = Gdk.Display.get_default();
 
173
 
 
174
    foreach (var win in this.bamf_application.get_windows()) {
 
175
      X.Window xid = 0;
 
176
 
 
177
      if (win is Bamf.Window) {
 
178
        if (win.get_window_type() != Bamf.WindowType.NORMAL)
 
179
          continue;
 
180
 
 
181
        xid = win.get_xid();
 
182
      }
 
183
      else if (win is Bamf.Tab) {
 
184
        xid = (X.Window) (win as Bamf.Tab).get_xid();
 
185
      }
 
186
 
 
187
      if (xid > 0) {
 
188
        var xwin = Gdk.X11Window.foreign_new_for_display(dpy, xid);
 
189
 
 
190
        if (xwin != null) {
 
191
          xwin.focus(timestamp);
 
192
          focused = true;
 
193
        }
 
194
      }
 
195
    }
 
196
 
 
197
    return focused;
 
198
  }
 
199
}