Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [platform-swt-dev] GTK in CVS

Steve_Northover@xxxxxxx writes: 
> - positioning widgets such that they do not move when the parent is 
> resized (we are using a fixed + hacks)
> 
> - everything to do with redraw, damaged areas, forcing paints, etc.

Things don't quite compile for me here yet, so I can't look at the
actual problems - glancing through the code, a "mismatch" between the
way GTK wants to do things and the way SWT wants to do things is that
you're expecting certain things to be synchronous (resulting in calls
go gtk_widget_show_now(), forced gtk_widget_realize(), the size
request/allocation process, and so on), while GTK wants those things
to happen "lazily" in an idle handler. I would expect to have a lot of
problems with flicker/jumping, and plain old inefficiency, unless
we're careful about how this is set up.

> - making Display.sleep() work properly

Spent some time talking to Owen about this. GLib 2.0 has a revised
main loop that's intended to make this kind of thing easier to do.
There are some possible hacks for GLib 1.2.

As you know the GLib main loop is a general-purpose thing that can
contain any kind of "event source." Built-in sources are timeouts,
idles, and input handlers, for example.

In both versions the loop has four "steps":

 prepare - ask all sources a) do they already have events and
           b) when they definitely need to be asked again 
           (when do we need to wake up and ask again - e.g. 
           a timeout requires that we wake up after the remaining
           time elapses)

 poll - sleep on all file descriptors (descriptors are provided by
        certain kinds of source), with the min timeout from all
        prepared sources, until we get a descriptor event or a timeout

 check - ask all sources if they have events now, taking into account
         the results of the poll

 dispatch - dispatch the sources with events ready

In GTK 1.2, there is no way to break these apart. 
The available API is:

  g_main_pending(): prepare, if there are events return right away,
                    else poll with timeout of 0 and check, 
                    then return whether we have events.

                    (Different in 2.0 in that it always polls, even if
                     the prepare has events already, in order to
                     handle source priorities correctly.)
   
  g_main_iteration(): do the whole cycle including dispatch

From looking at Display.sleep() what we want to do is 
prepare/poll/check, but not dispatch, and with the usual poll timeout,
not a poll timeout of 0 as g_main_pending() uses. So GTK 1.2 does not
give us the appropriate API.

In GLib 2.0, we have exported API to do each of the steps. So there
are g_main_context_prepare(), g_main_context_poll(),
g_main_context_check(), etc. functions. Display.sleep() needs to call
g_main_context_prepare(), then get poll info with
g_main_context_query(), do the g_main_context_poll() with that info,
and then g_main_context_check().  In readAndDispatch(), I'm not sure
if we want just the g_main_context_dispatch(), or a full
g_main_context_iteration(), but something along those lines.

Basically the idea is to copy the code out of the static function
g_main_context_iterate() in glib/glib/gmain.c, removing the places
where it uses private API, those are just efficiency hacks.
(The code copy really shouldn't be required, I filed this bug report on that:
  http://bugzilla.gnome.org/show_bug.cgi?id=66290
 but it's past 2.0 API freeze so for now we have to reimplement a 
 few lines, not a huge deal.)

Anyway, this should give us what I take to be the correct semantics
for SWT, which is that Display.sleep() never processes events, just
sleeps until some arrive. (From the XtAppPeekEvent() man page, current
Motif Display.sleep() processes timeouts without returning however -
so maybe it's supposed to sleep until widget events arrive, and just
process other kinds of event?)

For GLib 1.2, things are going to be more exciting. The hack
we came up with for Display.sleep() is pretty broken, but is:

   while (g_main_iteration (FALSE)) /* FALSE means don't block, just
                                     * run already-ready events
                                     */
     {
        /* Here we get the X display connection file descriptor,
         * and block until it has data using poll() system call
         * directly on that single descriptor
         */
     }

The problem is that timeout and input event sources are not going to
wake us up out of the sleep. I don't think GTK 1.2 itself relies on 
either of these, but if SWT uses timers, we'd need to do a custom
SWT-specific hack to track those and be sure we pass an appropriate 
timeout to poll().

Another possible hack is to _always_ pass say a 50 ms timeout to
poll(), so we never accidentally lock up forever, but of course that
will mean constantly eating CPU at some low level. No more than the
current Display.sleep() implementation, of course.

Docs for 2.0 main loop stuff can be found here:
 http://developer.gnome.org/doc/API/2.0/glib/glib-the-main-event-loop.html

It may not be clear that gtk_main_iteration(), gtk_main(), etc. are
just trivial wrappers around the GLib stuff - the main loop was moved
to GLib in the 1.0->1.2 transition, and gtk_main_* remains as a
compatibility layer.

Havoc









 



Back to the top