Consume startup-notification APPLICATION_ID
This patch ensures we're showing the correct data when doing startup-notification. https://bugzilla.gnome.org/show_bug.cgi?id=612833
This commit is contained in:
parent
fe52a9e1a1
commit
c92ce5983d
11
configure.ac
11
configure.ac
@ -70,6 +70,17 @@ PKG_CHECK_MODULES(MUTTER_PLUGIN, gio-unix-2.0 gtk+-2.0 dbus-glib-1
|
|||||||
clutter-glx-1.0 >= $CLUTTER_MIN_VERSION
|
clutter-glx-1.0 >= $CLUTTER_MIN_VERSION
|
||||||
libstartup-notification-1.0
|
libstartup-notification-1.0
|
||||||
gobject-introspection-1.0 >= $GOBJECT_INTROSPECTION_MIN_VERSION)
|
gobject-introspection-1.0 >= $GOBJECT_INTROSPECTION_MIN_VERSION)
|
||||||
|
|
||||||
|
# This is for the newly added application id bits, we can replace this with
|
||||||
|
# a version check later
|
||||||
|
saved_CFLAGS=$CFLAGS
|
||||||
|
saved_LIBS=$LIBS
|
||||||
|
CFLAGS=$MUTTER_PLUGIN_CFLAGS
|
||||||
|
LIBS=$MUTTER_PLUGIN_LIBS
|
||||||
|
AC_CHECK_FUNCS(sn_startup_sequence_get_application_id)
|
||||||
|
CFLAGS=$saved_CFLAGS
|
||||||
|
LIBS=$saved_LIBS
|
||||||
|
|
||||||
PKG_CHECK_MODULES(TIDY, clutter-1.0)
|
PKG_CHECK_MODULES(TIDY, clutter-1.0)
|
||||||
PKG_CHECK_MODULES(ST, clutter-1.0 gtk+-2.0 libcroco-0.6 gnome-desktop-2.0 >= 2.26)
|
PKG_CHECK_MODULES(ST, clutter-1.0 gtk+-2.0 libcroco-0.6 gnome-desktop-2.0 >= 2.26)
|
||||||
PKG_CHECK_MODULES(BIG, clutter-1.0 gtk+-2.0 librsvg-2.0)
|
PKG_CHECK_MODULES(BIG, clutter-1.0 gtk+-2.0 librsvg-2.0)
|
||||||
|
@ -248,10 +248,9 @@ AppPanelMenu.prototype = {
|
|||||||
let focusedApp = tracker.focus_app;
|
let focusedApp = tracker.focus_app;
|
||||||
|
|
||||||
let lastSequence = null;
|
let lastSequence = null;
|
||||||
if (focusedApp == null) {
|
let sequences = tracker.get_startup_sequences();
|
||||||
let sequences = tracker.get_startup_sequences();
|
if (sequences.length > 0) {
|
||||||
if (sequences.length > 0)
|
lastSequence = sequences[sequences.length - 1];
|
||||||
lastSequence = sequences[sequences.length - 1];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the currently focused app hasn't changed and the current
|
// If the currently focused app hasn't changed and the current
|
||||||
@ -262,13 +261,17 @@ AppPanelMenu.prototype = {
|
|||||||
&& lastSequence.get_id() == this._activeSequence.get_id())))
|
&& lastSequence.get_id() == this._activeSequence.get_id())))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
this._focusedApp = focusedApp;
|
|
||||||
this._activeSequence = lastSequence;
|
|
||||||
|
|
||||||
if (this._iconBox.child != null)
|
if (this._iconBox.child != null)
|
||||||
this._iconBox.child.destroy();
|
this._iconBox.child.destroy();
|
||||||
this._iconBox.hide();
|
this._iconBox.hide();
|
||||||
this._label.setText('');
|
this._label.setText('');
|
||||||
|
|
||||||
|
if (focusedApp == null && lastSequence != null)
|
||||||
|
focusedApp = lastSequence.get_app();
|
||||||
|
|
||||||
|
this._focusedApp = focusedApp;
|
||||||
|
this._activeSequence = lastSequence;
|
||||||
|
|
||||||
let icon;
|
let icon;
|
||||||
if (this._focusedApp != null) {
|
if (this._focusedApp != null) {
|
||||||
icon = this._focusedApp.get_faded_icon(AppDisplay.APPICON_SIZE);
|
icon = this._focusedApp.get_faded_icon(AppDisplay.APPICON_SIZE);
|
||||||
|
@ -1224,10 +1224,16 @@ shell_app_info_launch_full (ShellAppInfo *info,
|
|||||||
meta_window_activate (info->window, timestamp);
|
meta_window_activate (info->window, timestamp);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
else if (info->type == SHELL_APP_INFO_TYPE_ENTRY)
|
||||||
filename = shell_app_info_get_desktop_file_path (info);
|
{
|
||||||
gapp = g_desktop_app_info_new_from_filename (filename);
|
gapp = g_desktop_app_info_new (shell_app_info_get_id (info));
|
||||||
g_free (filename);
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
filename = shell_app_info_get_desktop_file_path (info);
|
||||||
|
gapp = g_desktop_app_info_new_from_filename (filename);
|
||||||
|
g_free (filename);
|
||||||
|
}
|
||||||
|
|
||||||
if (!gapp)
|
if (!gapp)
|
||||||
{
|
{
|
||||||
|
@ -286,16 +286,16 @@ shell_window_tracker_is_window_interesting (MetaWindow *window)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* get_app_for_window_direct:
|
* get_app_from_window_wmclass:
|
||||||
*
|
*
|
||||||
* Looks only at the given window, and attempts to determine
|
* Looks only at the given window, and attempts to determine
|
||||||
* an application based on WM_CLASS. If that fails, then
|
* an application based on WM_CLASS. If one can't be determined,
|
||||||
* a "transient" application is created.
|
* return %NULL.
|
||||||
*
|
*
|
||||||
* Return value: (transfer full): A newly-referenced #ShellApp
|
* Return value: (transfer full): A newly-referenced #ShellApp, or %NULL
|
||||||
*/
|
*/
|
||||||
static ShellApp *
|
static ShellApp *
|
||||||
get_app_for_window_direct (MetaWindow *window)
|
get_app_from_window_wmclass (MetaWindow *window)
|
||||||
{
|
{
|
||||||
ShellApp *app;
|
ShellApp *app;
|
||||||
ShellAppSystem *appsys;
|
ShellAppSystem *appsys;
|
||||||
@ -306,7 +306,7 @@ get_app_for_window_direct (MetaWindow *window)
|
|||||||
wmclass = get_appid_from_window (window);
|
wmclass = get_appid_from_window (window);
|
||||||
|
|
||||||
if (!wmclass)
|
if (!wmclass)
|
||||||
return shell_app_system_get_app_for_window (appsys, window);
|
return NULL;
|
||||||
|
|
||||||
with_desktop = g_strjoin (NULL, wmclass, ".desktop", NULL);
|
with_desktop = g_strjoin (NULL, wmclass, ".desktop", NULL);
|
||||||
g_free (wmclass);
|
g_free (wmclass);
|
||||||
@ -322,12 +322,57 @@ get_app_for_window_direct (MetaWindow *window)
|
|||||||
app = shell_app_system_get_app (appsys, id);
|
app = shell_app_system_get_app (appsys, id);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (app == NULL)
|
|
||||||
app = shell_app_system_get_app_for_window (appsys, window);
|
|
||||||
|
|
||||||
return app;
|
return app;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get_app_from_window_group:
|
||||||
|
* @monitor: a #ShellWindowTracker
|
||||||
|
* @window: a #MetaWindow
|
||||||
|
*
|
||||||
|
* Check other windows in the group for @window to see if we have
|
||||||
|
* an application for one of them.
|
||||||
|
*
|
||||||
|
* Return value: (transfer full): A newly-referenced #ShellApp, or %NULL
|
||||||
|
*/
|
||||||
|
static ShellApp*
|
||||||
|
get_app_from_window_group (ShellWindowTracker *monitor,
|
||||||
|
MetaWindow *window)
|
||||||
|
{
|
||||||
|
ShellApp *result;
|
||||||
|
GSList *group_windows;
|
||||||
|
MetaGroup *group;
|
||||||
|
GSList *iter;
|
||||||
|
|
||||||
|
group = meta_window_get_group (window);
|
||||||
|
if (group == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
group_windows = meta_group_list_windows (group);
|
||||||
|
|
||||||
|
result = NULL;
|
||||||
|
/* Try finding a window in the group of type NORMAL; if we
|
||||||
|
* succeed, use that as our source. */
|
||||||
|
for (iter = group_windows; iter; iter = iter->next)
|
||||||
|
{
|
||||||
|
MetaWindow *group_window = iter->data;
|
||||||
|
|
||||||
|
if (meta_window_get_window_type (group_window) != META_WINDOW_NORMAL)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
result = g_hash_table_lookup (monitor->window_to_app, group_window);
|
||||||
|
if (result)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_slist_free (group_windows);
|
||||||
|
|
||||||
|
if (result)
|
||||||
|
g_object_ref (result);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* get_app_for_window:
|
* get_app_for_window:
|
||||||
*
|
*
|
||||||
@ -340,12 +385,12 @@ get_app_for_window (ShellWindowTracker *monitor,
|
|||||||
MetaWindow *window)
|
MetaWindow *window)
|
||||||
{
|
{
|
||||||
ShellApp *result;
|
ShellApp *result;
|
||||||
MetaWindow *source_window;
|
const char *startup_id;
|
||||||
GSList *group_windows;
|
|
||||||
MetaGroup *group;
|
|
||||||
GSList *iter;
|
|
||||||
|
|
||||||
result = NULL;
|
result = NULL;
|
||||||
|
/* First, we check whether we already know about this window,
|
||||||
|
* if so, just return that.
|
||||||
|
*/
|
||||||
if (meta_window_get_window_type (window) == META_WINDOW_NORMAL)
|
if (meta_window_get_window_type (window) == META_WINDOW_NORMAL)
|
||||||
{
|
{
|
||||||
result = g_hash_table_lookup (monitor->window_to_app, window);
|
result = g_hash_table_lookup (monitor->window_to_app, window);
|
||||||
@ -354,43 +399,44 @@ get_app_for_window (ShellWindowTracker *monitor,
|
|||||||
g_object_ref (result);
|
g_object_ref (result);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
return get_app_for_window_direct (window);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
group = meta_window_get_group (window);
|
/* Check if the app's WM_CLASS specifies an app */
|
||||||
if (group == NULL)
|
result = get_app_from_window_wmclass (window);
|
||||||
group_windows = g_slist_prepend (NULL, window);
|
|
||||||
else
|
|
||||||
group_windows = meta_group_list_windows (group);
|
|
||||||
|
|
||||||
source_window = window;
|
|
||||||
|
|
||||||
result = NULL;
|
|
||||||
/* Try finding a window in the group of type NORMAL; if we
|
|
||||||
* succeed, use that as our source. */
|
|
||||||
for (iter = group_windows; iter; iter = iter->next)
|
|
||||||
{
|
|
||||||
MetaWindow *group_window = iter->data;
|
|
||||||
|
|
||||||
if (meta_window_get_window_type (group_window) != META_WINDOW_NORMAL)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
source_window = group_window;
|
|
||||||
result = g_hash_table_lookup (monitor->window_to_app, group_window);
|
|
||||||
if (result)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
g_slist_free (group_windows);
|
|
||||||
|
|
||||||
if (result != NULL)
|
if (result != NULL)
|
||||||
|
return result;
|
||||||
|
|
||||||
|
/* Now we check whether we have a match through startup-notification */
|
||||||
|
startup_id = meta_window_get_startup_id (window);
|
||||||
|
if (startup_id)
|
||||||
{
|
{
|
||||||
g_object_ref (result);
|
GSList *iter, *sequences;
|
||||||
return result;
|
|
||||||
|
sequences = shell_window_tracker_get_startup_sequences (monitor);
|
||||||
|
for (iter = sequences; iter; iter = iter->next)
|
||||||
|
{
|
||||||
|
ShellStartupSequence *sequence = iter->data;
|
||||||
|
const char *id = shell_startup_sequence_get_id (sequence);
|
||||||
|
if (strcmp (id, startup_id) != 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
result = shell_startup_sequence_get_app (sequence);
|
||||||
|
if (result)
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return get_app_for_window_direct (source_window);
|
/* If we didn't get a startup-notification match, see if we matched
|
||||||
|
* any other windows in the group.
|
||||||
|
*/
|
||||||
|
if (result == NULL)
|
||||||
|
result = get_app_from_window_group (monitor, window);
|
||||||
|
|
||||||
|
/* Our last resort - we create a fake app from the window */
|
||||||
|
if (result == NULL)
|
||||||
|
result = shell_app_system_get_app_for_window (shell_app_system_get_default (), window);
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *
|
const char *
|
||||||
@ -588,7 +634,6 @@ on_startup_sequence_changed (MetaScreen *screen,
|
|||||||
SnStartupSequence *sequence,
|
SnStartupSequence *sequence,
|
||||||
ShellWindowTracker *self)
|
ShellWindowTracker *self)
|
||||||
{
|
{
|
||||||
/* Just proxy the signal */
|
|
||||||
g_signal_emit (G_OBJECT (self), signals[STARTUP_SEQUENCE_CHANGED], 0, sequence);
|
g_signal_emit (G_OBJECT (self), signals[STARTUP_SEQUENCE_CHANGED], 0, sequence);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -795,6 +840,32 @@ shell_startup_sequence_get_id (ShellStartupSequence *sequence)
|
|||||||
return sn_startup_sequence_get_id ((SnStartupSequence*)sequence);
|
return sn_startup_sequence_get_id ((SnStartupSequence*)sequence);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* shell_startup_sequence_get_app:
|
||||||
|
* @sequence: A #ShellStartupSequence
|
||||||
|
*
|
||||||
|
* Returns: (transfer full): The application being launched, or %NULL if unknown.
|
||||||
|
*/
|
||||||
|
ShellApp *
|
||||||
|
shell_startup_sequence_get_app (ShellStartupSequence *sequence)
|
||||||
|
{
|
||||||
|
#ifdef HAVE_SN_STARTUP_SEQUENCE_GET_APPLICATION_ID
|
||||||
|
const char *appid;
|
||||||
|
ShellAppSystem *appsys;
|
||||||
|
ShellApp *app;
|
||||||
|
|
||||||
|
appid = sn_startup_sequence_get_application_id ((SnStartupSequence*)sequence);
|
||||||
|
if (!appid)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
appsys = shell_app_system_get_default ();
|
||||||
|
app = shell_app_system_get_app_for_path (appsys, appid);
|
||||||
|
return app;
|
||||||
|
#else
|
||||||
|
return NULL;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
const char *
|
const char *
|
||||||
shell_startup_sequence_get_name (ShellStartupSequence *sequence)
|
shell_startup_sequence_get_name (ShellStartupSequence *sequence)
|
||||||
{
|
{
|
||||||
|
@ -50,6 +50,7 @@ typedef struct _ShellStartupSequence ShellStartupSequence;
|
|||||||
GType shell_startup_sequence_get_type (void);
|
GType shell_startup_sequence_get_type (void);
|
||||||
|
|
||||||
const char *shell_startup_sequence_get_id (ShellStartupSequence *sequence);
|
const char *shell_startup_sequence_get_id (ShellStartupSequence *sequence);
|
||||||
|
ShellApp *shell_startup_sequence_get_app (ShellStartupSequence *sequence);
|
||||||
const char *shell_startup_sequence_get_name (ShellStartupSequence *sequence);
|
const char *shell_startup_sequence_get_name (ShellStartupSequence *sequence);
|
||||||
gboolean shell_startup_sequence_get_completed (ShellStartupSequence *sequence);
|
gboolean shell_startup_sequence_get_completed (ShellStartupSequence *sequence);
|
||||||
ClutterActor *shell_startup_sequence_create_icon (ShellStartupSequence *sequence, guint size);
|
ClutterActor *shell_startup_sequence_create_icon (ShellStartupSequence *sequence, guint size);
|
||||||
|
Loading…
Reference in New Issue
Block a user