After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 621203 - GtkApplication support work
GtkApplication support work
Status: RESOLVED FIXED
Product: gnome-shell
Classification: Core
Component: general
unspecified
Other All
: Normal normal
: ---
Assigned To: Colin Walters
gnome-shell-maint
: 622914 (view as bug list)
Depends on: 643736 648651 664851
Blocks: 656634
 
 
Reported: 2010-06-10 13:50 UTC by Colin Walters
Modified: 2011-12-20 22:37 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
[ShellApp] Split off running state handling into separate structure (11.55 KB, patch)
2010-06-10 13:50 UTC, Colin Walters
committed Details | Review
Port to GDBus, except for gdmuser/ (12.25 KB, patch)
2010-06-10 13:50 UTC, Colin Walters
reviewed Details | Review
[ShellApp] Support GtkApplication, add actions API (18.42 KB, patch)
2010-06-10 13:50 UTC, Colin Walters
reviewed Details | Review
ShellApp: port to new GApplication API (28.85 KB, patch)
2011-05-15 16:57 UTC, Giovanni Campagna
none Details | Review
Application Menu: add support for showing GApplication actions (13.81 KB, patch)
2011-05-15 16:57 UTC, Giovanni Campagna
none Details | Review
ShellApp: port to new GDBusActionGroup and GMenuProxy API (20.09 KB, patch)
2011-11-16 00:14 UTC, Giovanni Campagna
reviewed Details | Review
Application Menu: add support for showing GApplication actions (18.39 KB, patch)
2011-11-16 00:15 UTC, Giovanni Campagna
none Details | Review
quick shot (729.19 KB, image/png)
2011-11-18 02:50 UTC, Matthias Clasen
  Details
Application Menu: add support for showing GApplication actions (21.04 KB, patch)
2011-11-18 14:16 UTC, Giovanni Campagna
none Details | Review
Application Menu: add support for showing GApplication actions (20.90 KB, patch)
2011-11-21 16:57 UTC, Colin Walters
none Details | Review
ShellApp: port to new GDBusActionGroup and GMenuProxy API (23.34 KB, patch)
2011-11-21 18:29 UTC, Giovanni Campagna
reviewed Details | Review
Application Menu: add support for showing GApplication actions (17.29 KB, patch)
2011-11-24 17:47 UTC, Giovanni Campagna
none Details | Review
ShellApp: port to new GDBusActionGroup and GMenuProxy API (17.25 KB, patch)
2011-11-25 23:44 UTC, Colin Walters
committed Details | Review
Application Menu: add support for showing GApplication actions (17.72 KB, patch)
2011-11-28 18:21 UTC, Giovanni Campagna
committed Details | Review

Description Colin Walters 2010-06-10 13:50:18 UTC
Series of patches to start hooking up with GtkApplication
Comment 1 Colin Walters 2010-06-10 13:50:21 UTC
Created attachment 163293 [details] [review]
[ShellApp] Split off running state handling into separate structure

This is a small memory usage optimization, and cleans up the code.
In particular, this will help for later patches which perform
more substantial operations on running apps.
Comment 2 Colin Walters 2010-06-10 13:50:23 UTC
Created attachment 163294 [details] [review]
Port to GDBus, except for gdmuser/

Primarily motivated by wanting the session bus as a singleton
hooked off of ShellGlobal for future work which will use GDBus.

gdmuser/ directory not ported because it's a huge hairy ball.
We do need to fix it eventually though; but I'm hoping there will
be some sane user management library to come out of the Fedora
account manager stuff that we can port to.
Comment 3 Colin Walters 2010-06-10 13:50:26 UTC
Created attachment 163295 [details] [review]
[ShellApp] Support GtkApplication, add actions API

Initial work to hook up with GtkApplication.  I need to make some
further changes to the GtkApplication DBus API so we don't need
to backref from the pid, among other things.
Comment 4 Florian Müllner 2010-06-11 12:40:53 UTC
Review of attachment 163293 [details] [review]:

Looks good - minor comments follow:

::: src/shell-app.c
@@ +36,3 @@
  * @short_description: Object representing an application
  * SECTION:shell-app
+

Missing *

@@ +66,3 @@
 static guint shell_app_signals[LAST_SIGNAL] = { 0 };
+static ShellAppRunningState * ref_running_state (ShellAppRunningState *state) G_GNUC_UNUSED;
+static void create_running_state (ShellApp *app);

Should be *ref_running_state

@@ +621,2 @@
     return 1;
+  if (app->state == SHELL_APP_STATE_RUNNING)

I'm not sure if that should be part of the patch - saying that "an app which is not running compares equal to any other app" is changing the function's behavior. I'm sure there's some rationale behind it, but I can't figure it out in the context of this patch. I suspect that it will become clear when reading the other patches, but then the change should be done there.

@@ +694,3 @@
 {
                                 ShellApp   *app)
+  g_assert (app->running_state != NULL);

Is there a strong reason for using g_assert over g_return_if_fail here? Same question below.
Comment 5 Dan Winship 2010-06-16 16:53:13 UTC
Review of attachment 163294 [details] [review]:

::: src/shell-app-usage.c
@@ +356,2 @@
+  if (strcmp (signal_name, "StatusChanged") == 0
+      || !g_variant_is_of_type (parameters, G_VARIANT_TYPE ("(u)")))

flip the sense of the conditional and just return early if it's not that, rather than indenting the entire rest of the function?

@@ +456,3 @@
   g_signal_connect (tracker, "app-state-changed", G_CALLBACK (on_app_state_changed), self);
 
+  g_bus_watch_name (G_BUS_TYPE_SESSION,

I think this would be simpler if you used g_bus_watch_proxy() instead of g_bus_watch_name()?

::: src/shell-global.c
@@ +879,3 @@
+  guint32 request_status;
+
+  reply = g_dbus_connection_call_sync (session,

Why don't you use g_bus_own_name here?

I suppose the answer is "because g_bus_own_name() makes it too difficult to abort if it can't acquire the name", but if so, that seems like people just need to beat davidz over the head more forcefully about this. It's not a convenience API if it's not convenient.
Comment 6 Dan Winship 2010-06-16 17:32:47 UTC
Review of attachment 163295 [details] [review]:

::: src/shell-app.c
@@ +910,3 @@
+                                    result, &error);
+  if (!reply)
+    return;

possibly leaking error

@@ +935,3 @@
+      g_variant_unref (action_data);
+      if (!enabled)
+        continue;

i think that's a bug? otherwise there's no point in having action->enabled, shell_app_action_get_enabled(), etc

@@ +1059,3 @@
+    }
+
+  app->running_state->name_watch_id = g_bus_watch_name (G_BUS_TYPE_SESSION,

again, can probably simplify by using g_bus_watch_proxy
Comment 7 Florian Müllner 2010-06-16 17:36:49 UTC
(In reply to comment #5)
> I think this would be simpler if you used g_bus_watch_proxy() instead of
> g_bus_watch_name()?

Note that g_bus_watch_proxy() has been "nuked": http://git.gnome.org/browse/glib/commit/?id=32f2e9a85be
Comment 8 Dan Winship 2010-06-16 19:52:36 UTC
oh, I was going by the current docs on library.gnome.org, which I guess are from the last tarball. Anyway, "the API g_bus_watch_proxy() has been replaced with" then.
Comment 9 Colin Walters 2010-06-17 02:52:04 UTC
(In reply to comment #4)
>
> I'm not sure if that should be part of the patch - saying that "an app which is
> not running compares equal to any other app" is changing the function's
> behavior.

Not quite, actually the behavior of the function has always been effectively that not-running apps compare equal.  Not that a not-running app compares equal to any other.

> @@ +694,3 @@
>  {
>                                  ShellApp   *app)
> +  g_assert (app->running_state != NULL);
> 
> Is there a strong reason for using g_assert over g_return_if_fail here? Same
> question below.

Mmmm...I did think about it but I think I prefer g_return_if_fail to be used solely as preconditions, whereas the purpose of g_assert() is to trap things more obviously if we later add another application state or something.
Comment 10 Dan Winship 2010-06-27 14:45:32 UTC
*** Bug 622914 has been marked as a duplicate of this bug. ***
Comment 11 Dan Winship 2010-06-27 14:47:18 UTC
Note from 622914: you should be able to remove dbus-glib-1 from the MUTTER_PLUGIN pkg-config line in configure.ac since it's now only used indirectly via the gdmuser library.
Comment 12 Giovanni Campagna 2011-05-15 16:57:32 UTC
Created attachment 187857 [details] [review]
ShellApp: port to new GApplication API

DBus GApplication API changed from 2.25 to 2.27/2.28. Update accordingly,
and also make ShellApp implement the new GActionGroup interface,
and change the way the dbus id is associated to the app so that
already active applications are picked up when the shell starts.
Comment 13 Giovanni Campagna 2011-05-15 16:57:43 UTC
Created attachment 187858 [details] [review]
Application Menu: add support for showing GApplication actions

Use the new GApplication support in ShellApp to create the application
menu. Supports plain (no state), boolean and double actions.
Includes a test application (as no other application uses GApplication
for actions)
Comment 14 Giovanni Campagna 2011-11-16 00:14:51 UTC
Created attachment 201495 [details] [review]
ShellApp: port to new GDBusActionGroup and GMenuProxy API

GDBusActionGroup and GMenuProxy are new objects in GIO 2.32 that
help with accessing menus and actions of remote applications.
This patch makes it possible for the shell to associate an
application with a dbus name and from that a GMenu, that will
be shown as the application menu.
Comment 15 Giovanni Campagna 2011-11-16 00:15:35 UTC
Created attachment 201496 [details] [review]
Application Menu: add support for showing GApplication actions

Use the new GApplication support in ShellApp to create the application
menu. Supports plain (no state), boolean and double actions.
Includes a test application (as no other application uses GApplication
for actions)
Comment 16 Matthias Clasen 2011-11-18 00:39:27 UTC
Gave this a quick try, but couldn't get it to work.

First I ran into an assertion in g_dbus_action_group_new_finish, after fixing that, your test application gave me assertions about various label or detailed_action arguments being NULL. After replacing all those, I end up with

    JS ERROR: !!!     message = '"model.get_item_link is not a function"'


Btw, if you want another testcase, the wip/gmenu branch of gtk has tests/testgmenu, which you can run with --export to get an dynamic menu exported.
Comment 17 Jasper St. Pierre (not reading bugmail) 2011-11-18 00:43:18 UTC
Sounds like your gobject-introspection bindings aren't up to date.

  $ cd gobject-introspection/misc
  $ python update-glib-annotations.py ../../glib
  $ jhbuild make
Comment 18 Matthias Clasen 2011-11-18 01:28:51 UTC
I did rebuild gobject-introspection, and Gio-2.0.gir does have GMenuModel stuff in it. If there is other extra-special sauce involved, then I may be missing it, indeed.
Comment 19 Matthias Clasen 2011-11-18 02:14:48 UTC
Doing that made the warnings about model.get_item_link go away...but still no menu :-( other than 'Quit gjs'
Comment 20 Matthias Clasen 2011-11-18 02:42:17 UTC
Ok, now I got to see a menu - exciting !


After adjusting testgmenu in gtk+ to the bus naming convention expected here, I got to see its menu too. 

Issues I found so far: 

- the menu does not get populated initially, I need to move the focus off and back for the menu to be filled.

- testgmenu has a label with an underline mnemonic in it: _Undo. I expect that we'll see that quite a bit in practice. It would be good to be robust against that and strip such underlines out

- testgmenu also has an example of radio items, using a single action with a string state - each item has a string parameter, and activating the item is expected to change the state to that string. This is not currently supported by your code, it seems
Comment 21 Matthias Clasen 2011-11-18 02:50:17 UTC
Created attachment 201636 [details]
quick shot
Comment 22 Matthias Clasen 2011-11-18 02:54:52 UTC
One more issue: 

- the appmenu does not pick up changes to the action group / menu while the app is in focus; I have to move the focus away and back to have new items show up. Sensitivity and state changes do show up without a focus change.
Comment 23 Giovanni Campagna 2011-11-18 12:47:53 UTC
(In reply to comment #22)
> One more issue: 
> 
> - the appmenu does not pick up changes to the action group / menu while the app
> is in focus; I have to move the focus away and back to have new items show up.
> Sensitivity and state changes do show up without a focus change.

Actually, it should be the opposite: GApplication does not propagate changes from the attached GSimpleActionGroup (I have a patch for that, but was waiting for wip/menus to merge before proposing it; now on bug 664328). On the other hand, GMenu changes should work, because GMenuExporter connects to the object provided by the app.

I'll look at it, using testgmenu from gtk
Comment 24 Giovanni Campagna 2011-11-18 13:22:29 UTC
testgmenu has a problem, at the moment: ShellWindowTracker uses org.gtk.Application.Hello to find applications that support GAction/GMenu, so anything not using GApplication won't be tracked, unless the shell is restarted.
If possible, it should be rewritten using GApplication and g_application_set_action_group / g_application_set_menu.
Comment 25 Matthias Clasen 2011-11-18 13:26:21 UTC
testgmenu has both a --export and a --import, if you want to play with that.
And the --import side clearly picks up changes. I guess you are right that we are not actually listening for changes of the action group, but of the menu model.

I want to keep testgmenu as the low-level handrolled example it is now.

You can also look at examples/bloatpad for a GtkApplication-using example.

To make the shell pick up its menus, you currently need to patch gtk_application_get_menu to return NULL (see the FIXME in there)
Comment 26 Matthias Clasen 2011-11-18 13:27:28 UTC
One more thing to work out: Do we want the shell to enforce the presence of a 'quit' item ? Or do we rely on apps to provide one in their app menu ?
Comment 27 Florian Müllner 2011-11-18 13:32:44 UTC
(In reply to comment #26)
> One more thing to work out: Do we want the shell to enforce the presence of a
> 'quit' item ? Or do we rely on apps to provide one in their app menu ?

I'm not particularly attached to "quit", but we need at least something for applications which don't export an app menu - both an empty menu and an unreactive app menu button are rather weird in my opinion.

(Now, our "quit" implementation is rather dumb, so it is probably a good idea to allow applications to implement their own)
Comment 28 Matthias Clasen 2011-11-18 13:55:36 UTC
The patch currently keeps the 'dumb quit' for apps which don't have an app menu.

I'm just wondering if we want the shell to look for an item with the 'quit' action, and if it isn't there, provide its own. The other alternative would be to provide a default 'quit' action from the GtkApplication side. Might be nicer.
Comment 29 Giovanni Campagna 2011-11-18 14:16:26 UTC
Created attachment 201663 [details] [review]
Application Menu: add support for showing GApplication actions

Use the new GApplication support in ShellApp to create the application
menu. Supports plain (no state), boolean and double actions.
Includes a test application (as no other application uses GApplication
for actions)

Tested more, now it works with testgmenu (although the shell must be
restarted, for the GApplication issue). Also, includes stripping of
_, and supports radio actions.
Comment 30 Matthias Clasen 2011-11-18 22:27:44 UTC
Works great now, excellent work!
Comment 31 Colin Walters 2011-11-21 16:57:16 UTC
Created attachment 201828 [details] [review]
Application Menu: add support for showing GApplication actions

Switch to strings instead of quarks
Comment 32 Colin Walters 2011-11-21 17:18:49 UTC
Review of attachment 201495 [details] [review]:

::: src/shell-app.c
@@ +996,3 @@
+                                                          &error);
+
+  if (error) {

Wrong brace style.

@@ +1005,3 @@
+    g_clear_error (&error);
+
+    if (state->dbus_cancellable) {

Wrong brace style.

@@ +1007,3 @@
+    if (state->dbus_cancellable) {
+      g_object_unref (state->dbus_cancellable);
+      state->dbus_cancellable = NULL;

I recommend g_clear_object (&state->dbus_cancellable)

@@ +1010,3 @@
+    }
+
+    if (state->name_watcher_id) {

Wrong brace style.

@@ +1059,3 @@
+                           state->dbus_cancellable,
+                           on_action_group_acquired,
+                           g_object_ref (self));

We're adding a ref on the ShellApp here, but I don't see it being unreffed in on_action_group_acquired() where it should be, right?

@@ +1078,3 @@
+      g_cancellable_cancel (state->dbus_cancellable);
+      g_object_unref (state->dbus_cancellable);
+      state->dbus_cancellable = NULL;

g_clear_object()

@@ +1084,3 @@
+    {
+      g_object_unref (state->remote_actions);
+      state->remote_actions = NULL;

g_clear_object()

@@ +1090,3 @@
+    {
+      g_object_unref (state->remote_menu);
+      state->remote_menu = NULL;

g_clear_object()

@@ +1111,3 @@
+         (can only happen if you restart the shell
+         in the middle of the session)
+      */

Hmm?  I don't understand how that can happen - if you restart the shell, it'll stop all of the dbus requests the previous process was doing, no?

@@ +1361,3 @@
+
+  if (state->remote_actions)
+    g_object_unref (state->remote_actions);

g_clear_object()

@@ +1364,3 @@
+
+  if (state->remote_menu)
+    g_object_unref (state->remote_menu);

g_clear_object()

@@ +1548,3 @@
+  /* We should have been transitioned when we removed all of our windows */
+  g_assert (app->state == SHELL_APP_STATE_STOPPED);
+  g_assert (app->running_state == NULL);

You could probably break out some of these assertion additions as a separate patch (up to you, fine with me to leave them in here)

@@ +1624,3 @@
+                                   g_param_spec_string ("dbus-id",
+                                                        "Application DBus Id",
+                                                        "The DBus well-known name of the application",

Honestly I just use "" for gobject property descriptions.  Nothing is going to read or use them here.  For gtk+, glade does use them, but long term we want it to read the docs from the .gir.

::: src/shell-window-tracker.c
@@ +616,3 @@
+    {
+      /* FIXME delete this - the connection may have gone away */
+      g_warning ("%s\n", error->message);

Yeah, it is slightly lame to warn here if the user starts and app and then immediately closes it and we're still trying the GetConnectionPid call.

@@ +631,3 @@
+  if (app)
+    _shell_app_set_dbus_name (app, data->bus_name);
+  else {

Wrong brace style.

@@ +679,3 @@
+  gchar *bus_name = NULL;
+
+  g_variant_get (parameters, "(s)", &bus_name);

You can use &s to avoid the strdup/free.

@@ +708,3 @@
+
+  g_variant_iter_init (&iter, g_variant_get_child_value (res, 0));
+  while (g_variant_iter_loop (&iter, "s", &bus_name)) {

Wrong brace style.

@@ +740,3 @@
+  g_dbus_connection_call (g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL),
+                          "org.freedesktop.DBus",
+                          "/",

Should be /org/freedesktop/DBus, I guess the bus driver doesn't care though.

@@ +752,3 @@
   self->window_to_app = g_hash_table_new_full (g_direct_hash, g_direct_equal,
                                                NULL, (GDestroyNotify) g_object_unref);
+  self->pid_to_dbus_connection = g_hash_table_new_full (g_direct_hash, g_direct_equal,

You can just use NULL for g_direct_hash and equal.
Comment 33 Giovanni Campagna 2011-11-21 18:29:07 UTC
Created attachment 201843 [details] [review]
ShellApp: port to new GDBusActionGroup and GMenuProxy API

GDBusActionGroup and GMenuProxy are new objects in GIO 2.32 that
help with accessing menus and actions of remote applications.
This patch makes it possible for the shell to associate an
application with a dbus name and from that a GMenu, that will
be shown as the application menu.

Fixed according to comments. I left in the g_assert() stuff
(not worth a patch, IMO) and the GParamSpec nick/blurbs (they're
not harming anyone there, and they're G_PARAM_STATIC_STRINGS).
Comment 34 Giovanni Campagna 2011-11-24 17:47:07 UTC
Created attachment 202080 [details] [review]
Application Menu: add support for showing GApplication actions

Use the new GApplication support in ShellApp to create the application
menu. Supports plain (no state), boolean and double actions.
Includes a test application (as no other application uses GApplication
for actions)

Rebased on current master (previous patch had conflicts with Lang.Class mass port)
Comment 35 Colin Walters 2011-11-25 20:01:24 UTC
Review of attachment 201843 [details] [review]:

One minor bit.

I think we should replace the ListNames code though with an X property that GtkApplication puts on the window.  Ryan was going to look at that.

::: src/shell-window-tracker.c
@@ +708,3 @@
+
+  g_variant_iter_init (&iter, g_variant_get_child_value (res, 0));
+  while (g_variant_iter_loop (&iter, "s", &bus_name))

This leaks bus_name; you want to use "&s" (and make bus_name const char *).
Comment 36 Giovanni Campagna 2011-11-25 20:53:41 UTC
(In reply to comment #35)
> Review of attachment 201843 [details] [review]:
> 
> One minor bit.
> 
> I think we should replace the ListNames code though with an X property that
> GtkApplication puts on the window.  Ryan was going to look at that.

Ok. Is there any place to track this work, or should I just wait for commit to glib master?

> ::: src/shell-window-tracker.c
> @@ +708,3 @@
> +
> +  g_variant_iter_init (&iter, g_variant_get_child_value (res, 0));
> +  while (g_variant_iter_loop (&iter, "s", &bus_name))
> 
> This leaks bus_name; you want to use "&s" (and make bus_name const char *).

No, g_variant_iter_loop frees before each round. (or at least, it's documented as such).
In any case, we can avoid the allocation, and use &s.
Comment 37 Colin Walters 2011-11-25 23:44:42 UTC
Created attachment 202159 [details] [review]
ShellApp: port to new GDBusActionGroup and GMenuProxy API

Rebased - use _DBUS_APPLICATION_ID property, drop ListNames code.
Comment 38 Colin Walters 2011-11-25 23:46:34 UTC
(In reply to comment #36)
> (In reply to comment #35)
> > Review of attachment 201843 [details] [review] [details]:
> > 
> > One minor bit.
> > 
> > I think we should replace the ListNames code though with an X property that
> > GtkApplication puts on the window.  Ryan was going to look at that.
> 
> Ok. Is there any place to track this work, or should I just wait for commit to
> glib master?

I just went ahead and pushed a commit to do it to the wip/gmenus branch of gtk+.  This bug now depends on the mutter bug to read it, and I rebased your patch to consume it.
Comment 39 Colin Walters 2011-11-25 23:47:42 UTC
(In reply to comment #36)
>
> No, g_variant_iter_loop frees before each round. (or at least, it's documented
> as such).

Oh, I see...weird.

> In any case, we can avoid the allocation, and use &s.

Yeah.  This code is gone now though =)
Comment 40 Matthias Clasen 2011-11-27 17:50:37 UTC
Some comments from looking at the code on the branch:

- I've recently changed the GTK+ implementation to do activation instead of change_state calls for stateful a tions. This is how things are supposed to work. For a boolean action, just activating it without a parameter is toggling it, and for a string-valued action, activating it with a string parameter is setting the state to that value.  We need to do the same here.

- I don't see any reason for supporting float-valued actions here. Its not called for in the designs, and doing it will only encourage crazy stuff.
Comment 41 Giovanni Campagna 2011-11-28 18:21:45 UTC
Created attachment 202316 [details] [review]
Application Menu: add support for showing GApplication actions

Use the new GApplication support in ShellApp to create the application
menu. Supports plain (no state), boolean and double actions.
Includes a test application (as no other application uses GApplication
for actions)

Support for 'd' removed, change_action_state() replaced with activate_action()
(although I now wonder what change_action_state() means)
Comment 42 Matthias Clasen 2011-11-29 12:01:06 UTC
change_action_state does just what the name says, it changes the state. But it is just conceptually cleaner to have items always activate actions, and have the state change happen as a side-effect of the activation.
Comment 43 Matthias Clasen 2011-11-30 12:49:37 UTC
Can we get the latest patch on the wip/menus branch ?
Comment 44 Giovanni Campagna 2011-12-08 21:16:45 UTC
I've just updated wip/menus-rebase2 to accomodate the latest changes in gio.
Comment 45 Giovanni Campagna 2011-12-08 21:18:06 UTC
(In reply to comment #44)
> I've just updated wip/menus-rebase2 to accomodate the latest changes in gio.

No wait, gio changed again...
Comment 46 Colin Walters 2011-12-20 22:37:41 UTC
Attachment 202159 [details] pushed as 8764253 - ShellApp: port to new GDBusActionGroup and GMenuProxy API
Attachment 202316 [details] pushed as 4debedb - Application Menu: add support for showing GApplication actions