Come calm content serene and sweet

HangingMost themes place the icon of the current application somewhere on the titlebar. Some operating systems (notably OS X) allow you to drag this icon as if it was the very file which is being viewed in that window.

This behaviour has been suggested for Metacity in the past. One of the two main problems with implementing it is that we have no way to identify the document being viewed in a window; we only barely have a way to identify the application.

In a blog post last week, Michal Hruby suggests a new window property to indicate the URI of a window’s current document. This spilled out onto wm-spec-list this morning. (“NEW” in the title is a typo for “NET”.)

Such a property is a matter for the toolkit to set, rather than the window manager. But if it was available, it would make the lives of window managers a little easier: not only would it make the window icon dragging possible, but it would also allow window matching by document or even document type, as well as by application.

Photo © Glamhag, cc-by-nc-sa.

More CSS thoughts

Call... (4 of 4) [2007 - Day 174 - Edge]The recent discussion about CSS themes looks as though it may become one of the most interesting new ideas in theming in recent years. Here are some further thoughts on what may evolve from this.

An alternative. There is no general way, and few special ways, to convert expression-based v1 and v2 themes to the hypothetical box-based CSS themes.  Therefore this would need to be an alternative theming system, without any upgrade path leading to it.

Document structure. CSS exists to style documents.  In our case the document is purely notional rather than existing somewhere as a file, so we have great leeway in its representation.  As I mentioned earlier, there are multiple ways in which we can use the ideas of element name, ID, and class to represent what we want to do.  The guiding principle is not what would be easiest to implement but what would cause least astonishment to new theme authors.  After some thought, I think such a layout might look like this:

<frame class=”maximized”>
<area class=”titlebar”>
<button class=”menu”/> <!– possibly others –>
<button class=”minimize”/>
<button class=”maximize”/>
<button class=”close”/> <!– possibly others –>
<area class=”content“/>

  • Feel free to disagree and to come up with alternatives.
  • There are no attributes on any element.  Attempts to select on attributes will fail.  The class is written as an attribute only for notational convenience: hence the italics.
  • Class is used instead of identifier because it’s not impossible that some implementation of this scheme will wish to have multiple buttons with the same function on a frame.

CSS3. Almost everything we already have can be represented in CSS level 2, and there is no immediate need for level 3.  The sticking point mentioned earlier was the window icon being part of the title in Atlanta.  However, this can be implemented in CSS2 as follows:

title:before {
content: url("metacity:icon");

where metacity:icon is a magic URL which returns the current application icon.  (But it might be wise not to use the name “Metacity” in this format, in case other window managers might like to use it; that goes for vendor-specific extensions, too.  Maybe we should use -wm-.)  That said, I am salivating over the possibilities of the new round attribute to background-repeat.

However, there is one piece of level 3 we absolutely need: we will need to allow border-radius at least on the frame, if not on the subsidiary elements.

Implementation. A format is independent of implementations, of course, but we need at least one implementation in order to test things. There have been a few possible implementations suggested:

  • webkit. This would work and reuse a lot of code, but I’m a little wary of embedding a web browser into the window manager.
  • nbtk. This seems to be missing a lot of what we need at present.
  • libccss. This has more of what we need, but still there’s a lot left open to us to implement, and a lot of what it implements we don’t need.  It also doesn’t allow us to define new colours, which we need, and appears not to implement sibling selectors, which we will probably also need.
  • Using libcroco for parsing and cascading and building the rest ourselves. This is slightly more work than using nbtk or libccss, but may be necessary because of the particularly specialised nature of what we are doing here.

Justification. One of the things people seem very keen on is how the window title is justified.  In the box model, the correct way to do this is with the auto keyword on the padding or margins of the title, and not using a text-justify declaration (since the title only has one line of text which fits snugly in its own content box).  However, since people are bound to try to use text-justify anyway, perhaps we should allow them to do so, and merely interpret it as another way of setting the padding.

Things we need to implement: The whole box model; several kinds of border pattern; basic generated content for the title; various kinds of text styling for the title; ability to use pseudoclasses to prelight and press buttons.

Things we should ignore: Padding on the frame.  Height and width set on the frame, or the content box.  Perhaps: Any theme without proper metadata.  If we’re doing things the same way as in v2, the font-family, font-weight, and font-style set for the title.  (Or should we allow themes to specify a font?)  Should we give a warning if a theme attempts to use anything we don’t support?

Photo © Jonathan W, cc-by-nc-nd.

Further thoughts on extending the window menu

alpine strawberryThe previous post about extending the window menu caused a great deal of discussion. It would seem that our readers would be interested in an implementation.  Thomas is considering working on this after the window matching experiments are more stable.

Now, we can imagine that any package might want to add menu options when it was installed, and delete them when it was removed.  Let us not concern ourselves for the moment with how a menu option and its effects are represented, other than assuming that it may be represented by an ASCII string. Rather, let us consider the ways in which a newly-installed application may wish to add menu options.  We are concerned with two kinds of menu option:

  • ∀: these appear on every window menu, for as long as the application is installed.  It need not be running.  For example, Take screencast should be available when Istanbul is installed and removed when Istanbul is removed.
  • ∃: these appear only on the menus of windows created by the application itself.  For example, Play should appear on Rhythmbox‘s window menu, but not on other applications’ menus, even if Rhythmbox is running.  (Otherwise, how would a user tell the difference between Rhythmbox’s Play and the Play of Totem?)

Users should have the option of disabling any ∀ options which are currently installed; the full set of ∀ options would be available in some kind of settings dialogue where a decision could be made about which options belonged on the list.  It should be noted that Minimize, Maximize, Close, etc., are the ∀ of the window manager itself.

So, where should these settings be stored?

  • In X properties on windows: The ∀ options would be stored as properties on the root window, and the ∃ options as properties on the windows involved.  This would be the simplest to implement, but who has the responsibility to set the property on the root window, and where does the data come from?
  • In GConf: This would only work for ∀ options.  It’s presumably a better plan than keeping them on the root window, though, and we could still use X properties for the ∃ options.
  • In /usr/share/applications/*.desktop: This is the way which would integrate best with package management, but would cause rather a performance hit as all the .desktop files would need to be scanned when the WM started up, and then there would need to be some kind of particularly clever window matching to work out which .desktop file corresponded to which windows for ∃.

Some kind of hybrid approach may be best: we could keep the ∀ menu options in .desktop files, and have a utility program that was run when any package was added or removed, to update GConf with the values.  Or perhaps this updating could be done in the control centre, when the user chose which subset of ∀ options they wanted.  Then we could keep ∃ options as properties on the windows, and rely on the toolkits to update them (perhaps even by parsing the application’s .desktop file).

Photo © van swearingen, cc-by-nc-sa.

The window menu

French Woodland StrawberryThe window menu is the menu you see when you click the menu button (which usually has the window icon on it), or right-click the titlebar. An identical menu appears when you right-click an application’s entry in the task switcher on the panel, although this menu is owned by libwnck rather than Metacity and is manually synchonised. The contents of both menus are currently fixed. Let’s treat them as the same menu.

The menu currently has around a dozen options.  What is the optimum length for this menu?

These are the current contents. Which of these should not be in the menu by default?

  • Minimise
  • Maximise
  • Move
  • Resize
  • Always on top (checkbox)
  • On every workspace / On only this workspace (radio buttons) ★
  • Move to workspace above, to the right, below, to the left (four separate options, only the applicable ones being visible) ★
  • Move to another workspace (leading to a submenu) ★
  • Close

Some say that the workspace options (★) are overkill. They are by far the most complicated options in the menu, and they take up a large amount of space even for people who do use workspaces.  Perhaps that’s not everyone; if workspaces are something that only advanced users are aware of, maybe these options ought to be enabled separately.

There are other things we could put on the window menu, if it doesn’t get too crowded.  What extra options would you like to see there?

  • Take a screenshot of this window
  • Share this window with another user using VNC
  • Screencast this window and upload it somewhere using Istanbul
  • Anything you can bind a keystroke to.  (Nargery: This would be kept as a hint on the root window, encoded either as a keybinding name (e.g. “toggle_shaded“) or as a representation of an EWMH command.)
  • Similarly, application-specific options, given in a hint on the window itself: so your music player could have play, pause, and so on when you clicked its entry in the task switcher; consider how this could move towards replacing permanent notification applets, evolving into being part of notifisation in Metacity 2, and how useful it might be in gnome-shell.
  • By analogy with right-clicking on the desktop allowing you to set the wallpaper, perhaps “Edit window borders“, which would take you to a dialogue which let you reorder the buttons, modify which user-chosen options were in the window menu, pick a window border theme, and perhaps even do some light theme editing.
  • …your ideas here…

Photo © Beautiful Rust, cc-by-nc-nd.

Towards a third version of the theme format: some design goals

Eggistentialism 1.5 or Three of a Perfect PairWhen we add features to the theme format, they must be added all in one go for reasons which were explained earlier. We are currently on version 2 of the theme format. In case there is ever a version 3, here are some of our design goals.  Not all of these may necessarily be met when and if it happens.  These are not in order of importance.

  1. Standard format. If possible, it should use standard file formats rather than custom ones.  This helps build tools, it helps code reuse, and it helps users learn the format.
  2. Editable. It should be designed such that it’s possible to write a theme editor which is easy to understand and use.
  3. Delegation. It would be useful if at least some of the code to parse and render the theme files was in a pre-existing library rather than being part of Metacity itself.
  4. Shareability. It should be at least possible to use the same theme format with various other window managers, which could perhaps be helped by keeping the code in an LGPL library.
  5. Single file. There should be a standard format for keeping all files associated with a theme in a single file, at least for both distribution and installation.  This will save the end user from ever having to deal with tar or zip.
  6. Subthemes. It should be possible to write a theme which inherits some of its attributes from an existing parent theme.
  7. Named colours. It should be possible to give identifiers and descriptions to a subset of colour constants so that the theme artist can override them on the fly.  (This is perhaps already solved given that we can use colours out of GTK themes.)
  8. Well-defined metadata. There should be visible metadata, including licence identifiers, which can contain a list of all authors as a theme gets remixed.  Theme editors should make it easy to keep this up to date.  In keeping with our use of standard formats, we should probably use Dublin Core for the fields and perhaps the same identifiers that DOAP uses for licences.  The casual theme artist should never see any of this, of course.
  9. Upgrade path. It should be possible to convert themes in version 1 or version 2 format to version 3 format automatically.  Conversion from other WM’s formats would be a nice touch.
  10. Minimum power. We don’t need to be able to do everything that v2 can do.  We do need to be able to do everything that is commonly done in v2.  (For example, v2 allows you to have a title “centred” ⅔ of the way across the titlebar.  This has probably never been used, and it’s no big problem if v3 can’t do it.  If it can’t centre the title in the middle, that’s more of a problem.)
  11. Maximum power. It should not be possible for the theme to get in the user’s way.  For example, it should not be possible to write a theme which obscures the contents of windows; otherwise it would not be possible to switch away from it.  Neither should it be possible to solve the Towers of Hanoi in the theme engine.  People have better things to do with their time.

Your thoughts on these and your suggestions for other goals are welcome, gentle reader.

Photo copyright © bitzcelt, cc-by-nc-nd.

Squib of the day: “(as root)”

GNOME bug 549389, which has a couple of duplicates, says that if a window is owned by an app which is running as a user other than the user who’s running Metacity, then it should have “(as fred)” on the titlebars, just as it would have “(on chiark)” or whatever if you were running the app remotely.  The obvious very useful case here is to have “(as root)” when you’re running a program as root, to remind you to be careful.

The code to do this exists in Bugzilla now, so we can check it into trunk at any point.

Other suggestions, some better than others, have included:

  • Use an alternative theme for root windows
  • Draw a red border around the window
  • Use a label (a space as big as the titlebar immediately below it) saying “Root process”
  • Say “(as superuser)” instead of “(as root)” in case users don’t know what “root” means
  • Have a hint not to write the username in the titlebar so that apps which generally run as root, like the package manager, don’t have baffling information all over their titlebar.

meta_warning() and dialogue boxes

meta_warning exampleI didn’t expect to get useful suggestions from the Linux Haters’ blogs, but here’s something that might fly: they point out that warnings from the window manager end up in .xsession-errors where nobody ever sees them. But now that we’re using Zenity for dialogues throughout, there’s no reason why we can’t adapt meta_warning() to put up a dialogue every time a warning is issued, which might alert users to useful things, such as why they can’t bind the keystroke they want.  Having a way to turn this off might also be helpful.

Zenity, sessions, and window matching

Apples &amp; Oranges - They Don't CompareIt has been pointed out that session management in Metacity is currently a bit broken. Firstly, it leaves a lot of useless files around. I assume that the only session file which is really necessary is the most recent one. Secondly, I recently found and fixed a bug where Metacity actually crashed when attempting to save a session. I wonder nobody had found it before, but maybe this shows that session management doesn’t get used, or at least looked at, very much. Thirdly, there’s still a bug in the session management that I found the other day while fixing Zenity support, wherein it tries to put up a dialogue before closing the session… and then always quits, so you can’t see what you were told.

It seems to me that session management is three-quarters of window matching, but isn’t half as useful.  It further seems to me that if window positions were remembered properly during day-to-day use, they would be remembered properly across sessions.  This seems to be a rather compelling argument for dropping session handling entirely and adding some kind of window matching in its place.  After all, it wouldn’t affect our claim to be a lightweight window manager to drop one broken feature and add a more useful one instead.

Photo © TheBusyBrain, cc-by.

Squib of the day: keep the menu in one place

At present the system menu, which you see when you right-click anywhere on the titlebar, left-click the menu button, or right-click an entry on the pager, is hard-coded separately into Metacity and libwnck, and required to be the same in both places.

I’ve been considering the idea of making it a property on the root window called, say, _METACITY_SYSTEM_MENU. Let’s think about how this could look. It would need multiple lines, and multiple fields for each line; so let’s say the lines are delimited by newlines and the fields by tabs, for easier processing. The first field in a line would dictate the function of the line. If it began with a star it would be something special, and we only need to define two of these, “*workspacemove” for “move up, down, left, right a workspace” and “*workspacemenu” for the submenu of workspaces.

Let’s say, though, that if it began with a colon it would represent an EWMH message.  A naive approach would be to send these messages when they were chosen; a more efficient approach would be to fake one up and pretend it had been received, to avoid the round trip to the X server. NARGERY: Let’s say that it consists of a number of subfields separated by colons; the first is the atom for the message_type; the second is “W” if the window field is to be filled in with the ID of the current window, and empty otherwise; the third and following are the contents of data.l[n], with any decimal integer standing for itself, a blank standing for zero, a dot followed by any characters representing an atom, S standing for a source indication and T for the current server time.  Trailing blanks can be omitted.  (For these purposes we pretend that toggling _NET_WM_STATE_HIDDEN minimises and un-minimises.)

Alternatively we could simplify matters by using a percentage sign followed by one of the names of the keybinding actions, such as %close.  This would be simpler but less portable to other window managers, if this ever became some kind of a standard.

The remainingfields for an action would be the string which represented it in the current locale and possibly a string representing the keybinding, in case we didn’t want to work it out for ourselves.

Given all this, we’d avoid duplicating the menu in both programs, and more importantly we’d make it possible to add entries to the menu, as requested in GNOME bug 345233 and elsewhere.  It has been suggested, for example, that if you have a program installed that allows you to share windows across the network, every window should give you the option of doing so in the system menu.  That could quite easily be done using “%run_command_n” here.

(Written during a long compile, so apologies if it rambles.  Also bear in mind that squibs of the day are supposed to be blue-sky ideas!)

Photo © appaloosa, cc-by-nc-nd.

another crazy idea

Tomy Switch Switch controlsAlmost everything we bind keys to could be done with an external application via EWMH, and on my computer there’s no perceptible speed penalty.  (I’m sure there is on slower machines.)  Perhaps there should be a configure switch not to include the code to do everything except the things which pop up switchers (and another switch not to include those, in case you use superswitcher) and then we could supply a separate executable for people who’d turned them off, so that pressing the “move to workspace right” key actually did “metacity-move –right” or something.  Maybe it would reduce the memory footprint on faster machines.  Maybe on the other hand it wouldn’t be worth the trouble.

Photo © Telstar Logistics, cc-by-nc.