Sprout and the Bean

i returned from the gtk+ hackfest in brno a few days ago.

the biggest thing we dealt with is touch. you can probably read about that on various other blogs. we’re taking a somewhat minimalist approach this cycle with big plans for the future: event controllers. those are bits of code that treat sequences of events as higher level ideas. for example, a press-release mouse button sequence without substantial pointer movement is a “click”. this is somewhat different from our current model where it’s left to individual widgets to determine what constitutes this sort of interaction based on separate delivery of the individual events. naturally, this is almost the same idea as the philosophy of utouch: that most interesting touch interactions are gestures. this should make future integration of gtk and utouch rather natural.

i had a chance to meet with marek about dconf working better with nfs home directories. he’s working hard to make sure this will be working very nicely soon. i talked to emmanuele about gproperty and we came up with a solution for how we could improve the performance to the point where it’s improving all use cases and regressing none while providing what i believe to be an easier API for implementors.

the idea for removing support for grabs from gtk was met with general support. implicit grabs will be supported of course (like the sort of grab that happens when you click the mouse down until the point that you release it). the only sort of explicit grab behaviour that we care to support is the ‘popup menu’ case where you want a window to be dismissed when you click away from it. this will be offered as a simple boolean property on GtkWindow and the implementation will be done in the best way for each platform. there was an idea that we could even have a window manager hint to help us do this on X without the use of grabs (or other evil hacks like fullscreen input-only windows). there is presently nobody to tackle this task, but i may be able to find some time.

we’re going to deprecate gdk threads next cycle. (yay!)

we’re going to deprecate gtk_dialog_run() next cycle. (yay!)

there’s the increasing idea that we want to move away from using atk for accessibility purposes. it would be more efficient if we spoke to dbus directly, using our own abstraction that was kept in-tree and suited to our widgets. this abstraction could then also be made to support gtk accessibility on windows and mac in the future (instead of having an abstraction around an abstraction as would be the case if we tried to include atk as another option there). the plan for now is that it would continue to speak the same dbus protocol (which puts us pretty close to what qt is doing in this area).

i also spent some time hanging out with the documentation team who was having a hackfest next door. there seems to be a big change in focus there from working on user help to working on developer documentation (which we desperately need more of). gnome is pretty easy to use already, but i can’t tell you how many times i’ve heard that it’s difficult to develop for due to the lack of good documentation for beginners. hopefully good things will be coming soon.

15 thoughts on “Sprout and the Bean”

  1. What will be the recommended way to access GTK from another thread now? g_idle_add?

    [WORDPRESS HASHCASH] The poster sent us ’0 which is not a hashcash value.

  2. yes. dispatching back to the main thread was always the recommended way. gdk threads were only in case you were too lazy to figure out how to do it properly.

    besides, gdk threads never worked properly anyway (for example, they were always broken on win32).

  3. Why is the following bad?

    // A question dialog, or some sort of picker, e.g. file chooser, etc.
    GtkWidget *dialog = create_some_dialog();
    if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_OK)
    something = get_something(dialog);
    gtk_widget_destroy(dialog);
    use_it(something);

    You can split of course any function into two pieces, before and after, and pass context as a signal handler data, but why? Function stack is just as nice or nicer a place to store the context in a lot cases. Are there some problems with nested main loops?

    1. yes. precisely. nested main loops introduce quite a degree of uncertainty and unexpected reentrancy into your program. if gtk is the only event source, then you can limit this using things like modality, but in modern applications you have quite a few more sources (things like d-bus, for example). when an event comes in, it will usually not be running in context of your dialog, but in the odd case where the dialog is showing at the same time, it may. this unexpected concurrency (the event handler plus the state-on-the-stack of your dialog) has been shown in the past to introduce extremely tricky bugs.

      also consider that it could easily be possible for another gtk_dialog_run() to happen inside of your gtk_dialog_run()….

      you could argue that you’re happy to deal with that complexity, but it’s not just you. the biggest problem here is that people who call a function don’t expect that their code may re-enter before that function returns. when signal handlers are involved, particularly (as usually they are for the case of showing a dialog) you can have reentrancy as a side-effect of firing a signal. things get pretty weird fast…

  4. Just replace “during gtk_dialog_run” with “during the time when you have a single handler attached to the response signal” and you get exactly the same potential problems. For example, if you have a GtkFileChooserDialog shown, you have it no matter whether it’s sitting in gtk_dialog_run() or not. If you get something unexpected from dbus during that time then you have a problem no matter what (key is “unexpected”). In short, removing gtk_dialog_run() makes simpler cases much more difficult to implement, yet it doesn’t help solve complicated cases.

    1. Yevgen: arbitrary code is not impacted by the existance of a signal connection. that only impacts the person with the connection.

      let’s have a concrete example: say some message from dbus causes a signal to be emitted and a programmer connects to this signal and uses it to display a dialog to the user. that sounds pretty plausible.

      if the person showing the dialog shows it, connects to the response signal and returns, then the dbus handling code also returns immediately. good.

      if, instead, they use gtk_dialog_run(), then the dbus handling code is blocked until the dialog is dismissed. if another dbus signal comes in at this time (which is can because you have reentered the mainloop) then there are now two copies of the dbus handling code running at the same time. if there was a mutex in use there, you have a deadlock. perhaps there are more subtle problems, even.

  5. So if you hold a mutex and call gtk_dialog_run (!), and if some callback can try to acquire that mutex, then you can get screwed. Duh. On the other hand, not using gtk_dialog_run() means splitting any function that needs to ask for input (file, font, Yes/No, etc.) into two pieces; no more functions which ask user for input and return the result. That’s overkill.

    1. Yevgen: i think you missed the very point about what makes this so tricky: the person holding the mutex and the person calling gtk_dialog_run() are different people.

  6. “there’s the increasing idea that we want to move away from using atk for accessibility purposes. it would be more efficient if we spoke to dbus directly, using our own abstraction that was kept in-tree and suited to our widgets”

    Well, AFAIK, this is one of the options that Benjamin is thinking about. Not sure about how much this idea is increasing (so not sure how many other supporters Benjamin found on GTK hackfest), but fwiw, the conclusion on last hackfest was not getting rid of ATK in the long term. At least without answering all the questions still in the air.

  7. In your example (second post of 27 February), couldn’t not blocking the dbus handling code also give rise to unexpected results in some cases? (For example, if the dbus handling code might affect state on which the response handler is dependent?)

    If so, is one unexpected effect worse than the other? Apart from that, this continuation passing style isn’t what C programmers should expect to put up with unless there is a really pressing need, because continuation passing style in C is awkward, difficult to read and error prone. In functional languages that is not always the case, but C is not functional and it doesn’t have lambdas.

    On a side issue, I don’t immediately understand your “two copies of the dbus handling code running at the same time” which might deadlock on a mutex, because any one main loop is single threaded and I can’t see how that could happen. Possibly by “dbus handling code” you mean something different to what I understand by the expression.

Comments are closed.