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 578847 - Alt-Tab handling
Alt-Tab handling
Status: RESOLVED FIXED
Product: gnome-shell
Classification: Core
Component: general
unspecified
Other Linux
: Normal normal
: ---
Assigned To: gnome-shell-maint
gnome-shell-maint
Depends on:
Blocks:
 
 
Reported: 2009-04-13 16:31 UTC by Dan Winship
Modified: 2009-05-04 17:10 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
Abstract Alt-Tab handling out into a helper class (33.37 KB, patch)
2009-04-13 16:33 UTC, Dan Winship
none Details | Review
First attempt at Alt-Tab handling (18.00 KB, patch)
2009-04-13 16:33 UTC, Dan Winship
none Details | Review
First attempt at Alt-Tab handling (19.28 KB, patch)
2009-04-17 17:48 UTC, Dan Winship
none Details | Review
Remove some old compositor-related code that mutter doesn't need (3.54 KB, patch)
2009-04-28 14:22 UTC, Dan Winship
committed Details | Review
Fix some broken indentation and simplify nested if()s (9.15 KB, patch)
2009-04-28 14:22 UTC, Dan Winship
committed Details | Review
Reorganize tab popup code a bit more cleanly. (5.81 KB, patch)
2009-04-28 14:22 UTC, Dan Winship
committed Details | Review
Split screen->tab_popup and screen->ws_popup (5.13 KB, patch)
2009-04-28 14:22 UTC, Dan Winship
committed Details | Review
Push the tab/workspace popup abstraction completely into screen.c (12.18 KB, patch)
2009-04-28 14:22 UTC, Dan Winship
committed Details | Review
Create a MetaAltTabHandler abstraction to allow alternate implementations (26.13 KB, patch)
2009-04-28 14:22 UTC, Dan Winship
committed Details | Review
Third attempt at Alt-Tab handling (21.15 KB, patch)
2009-04-28 14:23 UTC, Dan Winship
reviewed Details | Review

Description Dan Winship 2009-04-13 16:31:24 UTC
OK, mutter and gnome-shell patches.

Currently, metacity has this thing called MetaAltTabPopup, which manages the popup window used by both Alt-Tab and the workspace-switching keys (eg, Ctrl-Alt-Left). The mutter patch changes it so that workspace-switching keys still use MetaAltTabPopup directly, but tab switching creates a MetaAltTabHandler object. The default MetaAltTabHandler just creates a MetaAltTabPopup just like the old code did, but you can call meta_alt_tab_handler_register() to register an alternate handler.

The gnome-shell patch implements a new MetaAltTabHandler subclass that emits signals and works with ShellWM to connect with the javascript code.

I think in a perfect world, MetaAltTabHandler would be an interface rather than an object, and altTab.js would implement a ClutterActor subclass that also implemented MetaAltTabHandler, so that then mutter would end up creating the clutter popup directly, without us needing to bounce things through ShellWM.

The current effects are pretty primitive; you get a clutterized version of the standard popup, with some rounded rectangles and a bit of tweening, and the selected window is highlighted by putting a translucent overlay over the window_group and just raising the selected window over it so that all of the other windows are darkened. The pop-up window has some issues. In particular, it will change size (but not position) if any window title is too long to fit in the existing popup. (BTW, I originally used TidyGrid, but it turns out that that has too many problems, such as the fact that it apparently has a minimum size of 200x200.)

I'm open to suggestions on both the interface and the effects, although I think we could just commit it once we're happy with the interface, and continue to improve the effects later.

Presumably we'll want to replace the workspace-switching popup with a similar interface...
Comment 1 Dan Winship 2009-04-13 16:33:06 UTC
Created attachment 132599 [details] [review]
Abstract Alt-Tab handling out into a helper class

The default implementation just uses the old MetaTabPopup, and the
workspace switcher still always uses that, for now.
Comment 2 Dan Winship 2009-04-13 16:33:38 UTC
Created attachment 132600 [details] [review]
First attempt at Alt-Tab handling
Comment 3 Colin Walters 2009-04-15 18:38:09 UTC
Is there a reason to have the default implementation and keep the old src/ui/tabpopup.c around?  Can we just say that mutter consumers are responsible for implementing alt-tab visualizations?
Comment 4 Dan Winship 2009-04-15 19:00:32 UTC
well, for the moment, the workspace-switching keys still use src/ui/tabpopup.c

I guess it depends on what o-hand are doing. If they don't need the default implementation (and I think they don't) then we can probably drop it.
Comment 5 Colin Walters 2009-04-16 14:14:19 UTC
Other quick comments:

* Constrain the proportions of the popup and ellipsize?  It gets sort of misshapen if one has a window with a long title.

* +  g_ptr_array_free (sth->windows, FALSE);

Should be TRUE, no?  I don't think anything else is using the segment.

* A comment about the relationship between these classes somewhere would be nice.  Maybe at the top of altTab.js.
Comment 6 Dan Winship 2009-04-16 17:04:01 UTC
(In reply to comment #5)
> * Constrain the proportions of the popup and ellipsize?  It gets sort of
> misshapen if one has a window with a long title.

Yeah, I just didn't want to spend too much time fiddling with the effects since we probably want something a little sexier eventually anyway. Also, tweaking the specific clutter effects is easier for casual contributors than figuring out the mutter-integration bits, so I figure other people might tackle that anyway.

> * +  g_ptr_array_free (sth->windows, FALSE);
> 
> Should be TRUE, no?  I don't think anything else is using the segment.

oops, yeah
Comment 7 Dan Winship 2009-04-17 17:48:44 UTC
Created attachment 132840 [details] [review]
First attempt at Alt-Tab handling

This fixes the layout a bit, and ellipsizes too-long labels. The code
is getting pretty ugly already... BigBox doesn't *quite* do what we want...
Comment 8 Owen Taylor 2009-04-23 20:06:08 UTC
If we consider this too be three pieces:

 A) Metacity additions
 B) gnome-shell C adapter object to make up for gjs deficiencies
 C) gnome-shell javascript

then it feels to me like some of the things that I'd expect to be in B):

 - Having a concrete class
 - Having properties

Are actually in A) instead. Admitting that all GObject code in C is a pain to write, it doesn't immediately seem harder to have MetaAltTab handler be an interface, and MetaAlTabHandlerDefault and ShellAltTabHandler objects that implement it.

(I see that you are also using as factory arguments, see below)

Some other comments about the Metacity code:

+MetaAltTabHandler *
+meta_alt_tab_handler_new (MetaScreen *screen,
+                          gboolean    immediate)
+{
+  if (handler_type == G_TYPE_INVALID)
+    handler_type = meta_alt_tab_handler_default_get_type ();
+
+  return g_object_new (handler_type,
+                       "screen", screen,
+                       "immediate", immediate,
+                       NULL);
+}

This - using a GType as the "factory" - is a pattern that I tend to avoid, because it binds poorly to many language bindings (though gjs may be OK) and doesn't accomodate "user data" when creating the object.

Is there any reason we can't just have:

 meta_screen_set_alt_tab_handler(screen, handler)

? (with a default being created on first use if none have been set by then.)

The counter-argument here is:

 - It probably *will* be OK in gjs - that is, Javascript has first class types as much as it has types as all, so AltTabHander.g_type is possible.
 - Sometimes we might actually want a factory; imagine something really heavyweight that we don't want to create on startup.
 - Other approaches to factories are incredibly annoying from GObject/C - you really don't want to have to create *two* types.
 - User data could be set on the screen

If we want to a) eventually use interfaces b) use GTypes as factories c) pass arguments by properties, then we'll have to either duck-type the properties or use properties on interfaces... with the the latter likely being the better choice (We'd need support in GJS for g_object_class_override_property()) The simpler alternative is to just have an init() method and avoid properties.

Just a few other comments on the Metacity changes:

 - Maybe stick to one GType per file, rather than combining the abstract and default implementations together?

- wasn't clear to me where the preview/get_window_pixbuf() stuff went. Maybe just needs to be commented in the log message.
Comment 9 Dan Winship 2009-04-23 20:28:00 UTC
(In reply to comment #8)
> If we consider this too be three pieces:
> 
>  A) Metacity additions
>  B) gnome-shell C adapter object to make up for gjs deficiencies
>  C) gnome-shell javascript
> 
> then it feels to me like some of the things that I'd expect to be in B):
> 
>  - Having a concrete class
>  - Having properties
> 
> Are actually in A) instead. Admitting that all GObject code in C is a pain to
> write, it doesn't immediately seem harder to have MetaAltTab handler be an
> interface, and MetaAlTabHandlerDefault and ShellAltTabHandler objects that
> implement it.

Yeah... I've forgotten now why I didn't do it that way. I definitely considered it at one point. And given what I said about wanting altTab.js to implement an interface directly, that makes even more sense, because, assuming gjs gets better GObject support in the future (or else we switch to seed), then we can just remove (B) and not need to change (A) at all.

> Is there any reason we can't just have:
> 
>  meta_screen_set_alt_tab_handler(screen, handler)

You mean where "handler" is actually a MetaAltTabHandler object rather than some sort of constructor for MetaAltTabHandler objects? The old code created a new tab-handling-thingy each time the user hit Alt-Tab, so I did the factory thing so it could keep working that way. But I guess we could say that meta_alt_tab_handler_hide() means "throw away the list of windows" too, so that it could then keep reusing the same one.

> - wasn't clear to me where the preview/get_window_pixbuf() stuff went. Maybe
> just needs to be commented in the log message.

It's gone. AFAICT it was part of the original metacity compositor code that wasn't being used by mutter.
Comment 10 Josh Adams 2009-04-28 00:42:53 UTC
I love the patch.  I would say that the behaviour on a dualhead configuration is a bit unfortunate (box spans the two screens, smack in the middle of the virtual desktop).  Still, intensely good looking :)
Comment 11 Dan Winship 2009-04-28 13:45:01 UTC
(In reply to comment #9)
> > Is there any reason we can't just have:
> > 
> >  meta_screen_set_alt_tab_handler(screen, handler)
> 
> You mean where "handler" is actually a MetaAltTabHandler object rather than
> some sort of constructor for MetaAltTabHandler objects? The old code created a
> new tab-handling-thingy each time the user hit Alt-Tab, so I did the factory
> thing so it could keep working that way. But I guess we could say that
> meta_alt_tab_handler_hide() means "throw away the list of windows" too, so that
> it could then keep reusing the same one.

As mentioned on Friday, this ended up being basically impossible without cleaning up the underlying code in metacity. So I did that, but then once I started implementing this, I realized it really doesn't make any sense at all; you end up having to have a meta_alt_tab_handler_is_visible() method, and replacing various screen->tab_handler!=NULL checks with meta_alt_tab_handler_is_visible(screen->tab_handler) instead, not to mention the somewhat odd "hide = restart" semantics mentioned above, etc. So after doing all the cleanup, I think ended up implementing this exactly like I did before, with a GType factory. Of course, we can change the exact nature of the factory. (It could be a GType+gpointer user_data, or you could set a constructor function instead of a gtype, or whatever.)

Of course, the cleanups are nice anyway. Patches to be attached. Once we decide we're happy with the general idea, I'll refile the mutter parts as a mutter bug.
Comment 12 Dan Winship 2009-04-28 14:22:32 UTC
Created attachment 133499 [details] [review]
Remove some old compositor-related code that mutter doesn't need
Comment 13 Dan Winship 2009-04-28 14:22:36 UTC
Created attachment 133500 [details] [review]
Fix some broken indentation and simplify nested if()s
Comment 14 Dan Winship 2009-04-28 14:22:40 UTC
Created attachment 133501 [details] [review]
Reorganize tab popup code a bit more cleanly.
Comment 15 Dan Winship 2009-04-28 14:22:44 UTC
Created attachment 133502 [details] [review]
Split screen->tab_popup and screen->ws_popup
Comment 16 Dan Winship 2009-04-28 14:22:48 UTC
Created attachment 133503 [details] [review]
Push the tab/workspace popup abstraction completely into screen.c
Comment 17 Dan Winship 2009-04-28 14:22:56 UTC
Created attachment 133504 [details] [review]
Create a MetaAltTabHandler abstraction to allow alternate implementations
Comment 18 Dan Winship 2009-04-28 14:23:17 UTC
Created attachment 133505 [details] [review]
Third attempt at Alt-Tab handling
Comment 19 Owen Taylor 2009-04-28 17:21:13 UTC
(In reply to comment #12)
> Created an attachment (id=133499) [edit]
> Remove some old compositor-related code that mutter doesn't need

Looks good to me, maybe should be combined with removing the get_window_pixmap() hook all-together, but that really is best done after removing compositor-xrender altogether.
Comment 20 Owen Taylor 2009-04-28 17:24:59 UTC
(In reply to comment #13)
> Created an attachment (id=133500) [edit]
> Fix some broken indentation and simplify nested if()s

Looks good, trusting you a bit that the logic is unchanged (since it's a little hard to figure out the old indentation from the patch)


Comment 21 Owen Taylor 2009-04-28 17:32:43 UTC
(In reply to comment #14)
> Created an attachment (id=133501) [edit]
> Reorganize tab popup code a bit more cleanly.

Looks likes a nice cleanup, maybe could do with a bit more of a verbose commit message about what's going on in the patch.

Comment 22 Owen Taylor 2009-04-28 17:34:23 UTC
(In reply to comment #15)
> Created an attachment (id=133502) [edit]
> Split screen->tab_popup and screen->ws_popup

Looks good.
Comment 23 Owen Taylor 2009-04-28 18:12:20 UTC
(In reply to comment #16)
> Created an attachment (id=133503) [edit]
> Push the tab/workspace popup abstraction completely into screen.c

Looks like a nice improvement.

meta_screen_ensure_workspace_popup (MetaScreen    *screen,
+                                    MetaWorkspace *initial_selection)

Hmm, having an "ensure" function with an argument is a bit weird... the expectation for an ensure function is that if the thing that you are ensuring already exists, it does nothing. Which is what happens here. But then what effect does the argument have? (Your patch seems to have a change from "always select" to "do nothing") May just need a comment explaining the handling of an already existing popup.

The change from using the XWindow to using the MetaWindow as the MetaTabEntryKey should be described in the commit message, or otherwise parts of this patch are hard to understand.
Comment 24 Owen Taylor 2009-04-28 18:52:02 UTC
(In reply to comment #17)
> Created an attachment (id=133504) [edit]
> Create a MetaAltTabHandler abstraction to allow alternate implementations

Generally looks very good. The patch makes a lot more sense to read on top of the cleanups.

Maybe there should be function docs on the MetaAltTabHandler? - I think ideally everything that is exported in include/ would have docs.

And one nit-pick:

+  MetaTabPopup *tabpopup;

SHould be tab_popup I think, consistently with what was elsewhere and the TabPopup naming.

I think all of these patches (with whatever improvements you want to make) could be filed on a single mutter bug (or maybe two - one for the cleanup, one for MetaAltTabHandler). You don't need to wait for additional review there (just provide a pointer to this bug), but it would be good to wait 24 hours or so after filing before committing in case anybody wants to provide feedback.
Comment 25 Owen Taylor 2009-04-29 19:24:04 UTC
The gnome-shell patch looks good to me. I'd like to see a comment somewhere explaining the ShellAltTabHandler / ShellWM relation and maybe giving some insight how this will work in a better future.

+        // BigBox complains if you put an ellipsized ClutterText into it
+        // directly! :-/

This is something I don't much like seeing without a bug URL. We shouldn't just live with the weirdnesses and bugs of BigBox, we should work to make sure that they get fixed, so we don't have to code around them.
Comment 26 Dan Winship 2009-05-04 14:37:17 UTC
mutter bits committed as bug 580917
Comment 27 Dan Winship 2009-05-04 17:10:57 UTC
and gnome-shell bits committed

(In reply to comment #25)
> The gnome-shell patch looks good to me. I'd like to see a comment somewhere
> explaining the ShellAltTabHandler / ShellWM relation and maybe giving some
> insight how this will work in a better future.

done. (in shell-alttab.c)

> +        // BigBox complains if you put an ellipsized ClutterText into it
> +        // directly! :-/
> 
> This is something I don't much like seeing without a bug URL. We shouldn't just
> live with the weirdnesses and bugs of BigBox, we should work to make sure that
> they get fixed, so we don't have to code around them.

The bug appears to have gone away since I wrote that comment. Probably fixed by the clutter text-actor-layout-height merge.