Opened 13 years ago

Last modified 13 years ago

#3056 closed defect

Unnecessary redraws on focus change and resize

Reported by: abligh Owned by:
Priority: normal Milestone:
Component: wxGTK Version:
Keywords: Cc: abligh, juliansmart, leio
Blocked By: Blocking:
Patch: no


GTK 2 / Linux / wxWidgets 2.6.2

wxWidgets appears to redraw windows unnecessarily on
focus change and resize. Enclosed is a 100 line
application demonstrating the two problems. The
application paints the entire redraw area a different
colour on each redraw. See how this works by wiping a
window over the test app. There are two (probably
related) problems.

  1. Focus change by clicking in the window causes an

unnecessary redraw. Run the app. Bring up a
non-overlapping window (e.g. a terminal). Click in the
terminal window. Click back in the test app window. You
will notice it is entirely redrawn, for no good reason.

  1. Resizing the window causes an unnecessary complete

redraw. Simply resize the window, and note that the
whole thing redraws. Redraw should be limited to those
parts of the window which are newly exposed.


Attachments (2)

redrawtest.cpp download (2.3 KB) - added by abligh 13 years ago.
Test application demonstrating redraw problems
redrawtest-nosubwindow.cpp download (1.8 KB) - added by abligh 13 years ago.
Test application showing different redraw problems without a subwindow

Download all attachments as: .zip

Change History (7)

Changed 13 years ago by abligh

Test application demonstrating redraw problems

comment:1 Changed 13 years ago by abligh

Interestingly, if you drop the subwindow and paint the frame
directly (as per redrawtest-nosubwindow.cpp - attached to
this mod), the first problem disappears but the second is
still there. Perhaps problem 1 only appears if the click is
in a subwindow of the window whose focus is changing (still
significant, obviously).

I assume this is GTK specific, but I have not tested any
other platform.

Changed 13 years ago by abligh

Test application showing different redraw problems without a subwindow

comment:2 Changed 13 years ago by juliansmart

Here's a clue about the redraw-on-focus behaviour:

It's GTK+ behaviour to send an expose event when focus
changes. Perhaps more logical behaviour (that I assume in my
own apps) is assuming that the app itself issues a redraw in
a focus event handler if it wants to redraw itself.

We may be able to enforce this by return true from
gtk_window_focus_in_callback (and _out_callback) so it
doesn't do its default thing. This seems to work but I don't
know what side-effects this will have.

comment:3 Changed 13 years ago by leio

I have planned to look at this beast at some point of time,
and optimize resizes and other cases, but I don't think I
can get to that before a week, or even a month.

I'm having seconds thoughts for having a GtkPizza in the
first place - maybe we could get away with only a
GtkEventBox. Anyhow, this is something for when I'm able to
actually study what all GtkPizza does.

Till then, some comments:

focus in and out default handlers queue a shallow draw on
the widget.
Internal docs for gtk_widget_queue_shallow_draw say:
Like gtk_widget_queue_draw(), but only windows owned by the
GtkWidget are invalidated.

And indeed as also noted in the mail address quoted, if
there is a focus, then there must be an indication of it, at
least when to follow some human interface guidelines.
To do things properly, we should look into if we can make
GtkPizza unfocusable. Suppressing focus_in and focus_out
would be an unclean hack, one of the kind that I'm wanting
to get rid of throughout the code.

As for second point, we do some evil things to the default
routines handling this in GTK+ - I believe we might even not
use the default backing pixmap niceties in GTK+. To me it
makes sense to by default expose the whole area, as the size
has changes, so you usually need to reposition controls and
so on. But for us sizers do that. I need to look into this
closer to say something more definite.

At least gtk_win.c is now nicely small and more
understandable with gtk1 out of the way. In fact, to me it
seems curiously too small now to do the things, we want it
to do, properly.

comment:4 Changed 13 years ago by juliansmart

If we want to maintain consistency on different platforms,
and solve this problem, then suppressing the redraw-on-focus
default behaviour is not an unclean hack (perhaps you can
explain why you think it is - are you arguing for adopting
auto-redraw-on-focus for all platforms?).

For the resize issue, I suspect that the full exposure event
may be generated by X11 at a low level, if GTK has passed
StaticGravity to XChangeWindowAttributes, so any change in
size will result in a full expose event. Perhaps we can
explicitly call XChangeWindowAttributes on the underlying
window attribute ourselves. (See window.cpp in wxX11 for use
of this attribute.) BTW passing -sync when running the
sample may help with debugging event handling.

comment:5 Changed 13 years ago by abligh

I've closed this as it works in 2.6.3 now.

Note: See TracTickets for help on using tickets.