Add per-window actions
GTK+ also exports window-specific actions, by putting the object path for the exported action group in the _DBUS_OBJECT_PATH X property. We add this action group to the app's muxer with a 'win' prefix, since that is what the exported menu expects. Whenever the focus window changes, we update the window-specific actions of its application, and emit notify::action-group to cause the app menu to be updated.
This commit is contained in:
parent
ab4a7c5237
commit
5290a9dd08
@ -244,6 +244,7 @@ const AppMenuButton = new Lang.Class({
|
||||
this._menuManager = menuManager;
|
||||
this._targetApp = null;
|
||||
this._appMenuNotifyId = 0;
|
||||
this._actionGroupNotifyId = 0;
|
||||
|
||||
let bin = new St.Bin({ name: 'appMenu' });
|
||||
this.actor.add_actor(bin);
|
||||
@ -522,8 +523,12 @@ const AppMenuButton = new Lang.Class({
|
||||
|
||||
if (this._appMenuNotifyId)
|
||||
this._targetApp.disconnect(this._appMenuNotifyId);
|
||||
if (targetApp)
|
||||
if (this._actionGroupNotifyId)
|
||||
this._targetApp.disconnect(this._actionGroupNotifyId);
|
||||
if (targetApp) {
|
||||
this._appMenuNotifyId = targetApp.connect('notify::menu', Lang.bind(this, this._sync));
|
||||
this._actionGroupNotifyId = targetApp.connect('notify::action-group', Lang.bind(this, this._sync));
|
||||
}
|
||||
|
||||
this._targetApp = targetApp;
|
||||
let icon = targetApp.get_faded_icon(2 * PANEL_ICON_SIZE);
|
||||
|
@ -557,6 +557,31 @@ shell_app_activate_window (ShellApp *app,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
shell_app_update_window_actions (ShellApp *app, MetaWindow *window)
|
||||
{
|
||||
const char *object_path;
|
||||
|
||||
object_path = meta_window_get_dbus_object_path (window);
|
||||
if (object_path != NULL)
|
||||
{
|
||||
GActionGroup *actions;
|
||||
|
||||
actions = g_object_get_data (G_OBJECT (window), "actions");
|
||||
if (actions == NULL)
|
||||
{
|
||||
actions = G_ACTION_GROUP (g_dbus_action_group_get (g_dbus_proxy_get_connection (app->running_state->app_proxy),
|
||||
meta_window_get_dbus_unique_name (window),
|
||||
object_path));
|
||||
g_object_set_data_full (G_OBJECT (window), "actions", actions, g_object_unref);
|
||||
}
|
||||
|
||||
g_action_muxer_insert (app->running_state->muxer, "win", actions);
|
||||
g_object_notify (G_OBJECT (app), "action-group");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* shell_app_activate:
|
||||
* @app: a #ShellApp
|
||||
@ -1081,7 +1106,7 @@ on_dbus_proxy_gotten (GObject *initable,
|
||||
|
||||
g_variant_get_child (menu_property, 0, "&o", &object_path);
|
||||
|
||||
state->remote_menu = G_MENU_MODEL (g_dbus_menu_model_get (g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL),
|
||||
state->remote_menu = G_MENU_MODEL (g_dbus_menu_model_get (g_dbus_proxy_get_connection (state->app_proxy),
|
||||
state->dbus_name,
|
||||
object_path));
|
||||
|
||||
|
@ -83,6 +83,8 @@ int shell_app_compare_by_name (ShellApp *app, ShellApp *other);
|
||||
|
||||
int shell_app_compare (ShellApp *app, ShellApp *other);
|
||||
|
||||
void shell_app_update_window_actions (ShellApp *app, MetaWindow *window);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __SHELL_APP_H__ */
|
||||
|
@ -413,6 +413,9 @@ update_focus_app (ShellWindowTracker *self)
|
||||
new_focus_win = meta_display_get_focus_window (shell_global_get_display (shell_global_get ()));
|
||||
new_focus_app = new_focus_win ? shell_window_tracker_get_window_app (self, new_focus_win) : NULL;
|
||||
|
||||
if (new_focus_app)
|
||||
shell_app_update_window_actions (new_focus_app, new_focus_win);
|
||||
|
||||
set_focus_app (self, new_focus_app);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user