Proposal: Titlebar widgeting specification
[This is a copy of an email I sent to the xdg mailing list, which was pretty much a ghost town]
I don't have any rock-solid plan for this specification, I'm just throwing it out there for discussion. I'm using the term "window manager" synonymously with "wayland compositor" throughout this email. The idea is that window managers could provide an API for applications to do either of the following:
- Add widgets to the title bar (such as labels, text inputs, buttons, checkboxes, combo boxes, etc...) to combine the benefits of CSD and window managers
- Get information about the window manager's appearance to implement CSD without off-putting the user
An API like this could then lead the way for real widgeting toolkits to integrate it into their syntax without much contrast. For example, GTK could have the headerbar use this API once GNOME's window manager supports this specification, or Qt could create a QTitleBar widget with a similar syntax to QToolBar (including functions like addWidget, addSeparator, and so on). This will allow both developers and users to get the best out of what both CSV and window managers have to offer, and to be relieved of having to pick one or even not getting to choose.
The challenge with creating something like this is that it will have to be very well designed if we want to avoid either driving developers crazy or destroying performance through something like a CSS parser. A design like this is possible, but still a challenge. There's a lot of possible ways that the API could look, so I'll give a brief template to get started:
#include <xdg/tbwidgets.h>
#include <time.h>
int main(int argc, char *argv[])
{
TitleBar *bar = get_titlebar(/* pointer to X11 Window / Wayland shell surface */);
TbWidget *checkbox = titlebar_add_widget(bar, titlebar_button, "click me!");
TbWidget *btn = titlebar_add_widget(bar, titlebar_button, "click me!");
TbWidget *label = titlebar_add_widget(bar, titlebar_label, "<--- click it!!!")
titlebar_widget_set_text(label, "<--- nevermind, don\'t click it!!!");
titlebar_widget_set_tooltip(label, "clicking it will trigger the end of the world");
titlebar_remove_widget(bar, btn);
update_titlebar(bar);
sleep(99); /* showtime! */
}
This template shows some basic functions that probably wouldn't change much in the future. The rest of the implementation could be done in many different ways, each with their own pros and cons. Here's a few of the questions that would need to be answered:
- Communication - How will the API communicate to window managers? One option is DBus. Another option could be a standard location for window managers to place libraries (eg. /usr/lib/tbwidgets/[openbox].so) which implement the specification, but this would require loading those libraries during runtime rather than compile time, and I'm not sure if that's even possible.
- Layout API - The possibilities for how apps may want to organize the titlebar in different situations is infinite. An app may want to set a maximum and minimum size for certain widgets, may want to use relative or absolute sizing/positioning, may want to hide/shrink/iconify/collapse certain widgets when the titlebar is too small, and so on, so a CSS property-like solution would be a bad approach. I think the only way to give users the ability to place widgets however they want is to have the user create a function that takes an unsigned int parameter for the titlebar's new length, and have a function like "titlebar_set_resize_callback(TitleBar *bar, void(*callback)(int));" that the user can pass their function to. This callback function could then be called by the internal API right before the widgets are rendered whenever the window is resized horizontally.
- Info detail - This question applies to the second part of the API as mentioned in the introduction. When an app wants to get data about a window manager so that it can implement CSD (or maybe even style the app based on the appearance of the window manager), what kind of info should be available and how should that info be organized? It could get very complicated to offer all of this information considering things like gradients, animations, borders, shadows, fonts, etc. I don't have any good solutions to this so far.
- On the topic of how this info will be designed, there would need to be a way for apps to be alerted when a window manager changes its appearance (aka theme or style). Obviously it would be a good idea to let users assign a callback to this event, but we can also give the user pointers to titlebar info rather than the actual info. That way when a user sets (for example) the background color of a CSD button to the background color of the window manager's buttons, the CSD button background color will sync with the window manager button's background color even when it is changed and a callback won't be needed.
Does anyone think this specification would be a good idea?