After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 763783 - GDK W32: Erase hidden layered windows before showing them
GDK W32: Erase hidden layered windows before showing them
Status: RESOLVED FIXED
Product: gtk+
Classification: Platform
Component: Backend: Win32
unspecified
Other All
: Normal normal
: ---
Assigned To: gtk-win32 maintainers
gtk-bugs
Depends on:
Blocks:
 
 
Reported: 2016-03-16 20:06 UTC by LRN
Modified: 2016-03-29 14:34 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
GDK W32: Erase hidden layered windows before showing them (8.34 KB, patch)
2016-03-16 20:06 UTC, LRN
none Details | Review
GDK W32: Erase hidden layered windows before showing them (8.33 KB, patch)
2016-03-17 11:14 UTC, LRN
none Details | Review
GDK W32: Erase hidden layered windows before showing them (8.35 KB, patch)
2016-03-26 01:05 UTC, LRN
none Details | Review
GDK W32: Erase hidden layered windows before showing them (8.35 KB, patch)
2016-03-28 20:13 UTC, LRN
committed Details | Review

Description LRN 2016-03-16 20:06:16 UTC
Layered windows are not redrawn automatically when they are made
visible. Instead Windows WM just re-uses their old contents until
we update them with UpdateLayeredWindow(). This is a problem,
because GDK does not keep track of hidden windows (does not redraw
them and, according to Company, ignores invalidations) and does
not redraw a window before making it visible. It schedules a redraw
when window is shown, but it doesn't happen immediately. Meanwhile
the window is made visible with the old content. That looks awful when
window content *should* have changed.

How to reproduce:
1) Create a window with a malleable widget (label, for example)
2) Set label text to "aaaaaaaaaaaa"
3) Show window
4) Hide window
5) Set label text to "bbbbbbbbbbbb"
6) Show window

Expected result:
Window is shown with "bbbbbbbbbbbb"

Actual result:
Window is shown with "aaaaaaaaaaaa" for the first 16 milliseconds or so,
then quickly switches to "bbbbbbbbbbbb".

Alternatively:
1) Run Glade
2) Hover over items in Glade widget palette to call the tooltip
3) Move pointer between items

Expected result:
Tooltip shows up with different text for different items

Actual result:
Tooltip shows up with the text for previous item, then quickly redraws
itself to contain the text for the new item (very noticeable if text
has different length, which means that tooltip width also changes).
Comment 1 LRN 2016-03-16 20:06:28 UTC
Created attachment 324138 [details] [review]
GDK W32: Erase hidden layered windows before showing them

If a layered window was hidden and is made visible, erase its
contents before showing it. GDK will schedule a redraw, but until
then we generally don't want to show old contents.
Comment 2 LRN 2016-03-16 20:11:33 UTC
Alternative version of this patch would take extra argument (GdkWindow corresponding to hWnd) and would clear and use actual layered window cache instead of creating a short-lived surface for that purpose. It would guarantee that window won't re-use old content, because it would clear the only cache we have, while current version keeps the cache intact and just erases the window (thus, if between erase and redraw something makes a call that ends in UpdateLayeredWindow() from cache, window will get old contents back).

I went with this version, because it doesn't require argument changes for ShowWindow() calls, just a name change.

Now that i'm thinking of it, this change should probably also cover SetWindowPos(), because it could be used to show a window. But that would be just for completeness, current version covers all the actual cases (that i could see in with real apps) where hidden window is shown with old contents.
Comment 3 LRN 2016-03-17 11:14:36 UTC
Created attachment 324168 [details] [review]
GDK W32: Erase hidden layered windows before showing them

v2:
* Fixed a typo
Comment 4 Fan, Chun-wei 2016-03-18 05:40:14 UTC
Review of attachment 324168 [details] [review]:

Hi LRN,

This reminds me of the video game "Psycho Pinball" where the game says "You need a quick eye to see this"--this issue is also seem from displaying various tooltips in the "Tool Palette" demo by hovering above the icons.

I believe Nacho is better than finding code styling issues than me, but I think otherwise the code looks and works well for me in this respect.

With blessings, thanks and cheers!

::: gdk/win32/gdkwindow-win32.c
@@ +1313,1 @@
     }

Ah, the nasty tab disguised as spaces that eludes our eyes... perhaps change these to spaces?
Comment 5 LRN 2016-03-26 01:05:30 UTC
Created attachment 324779 [details] [review]
GDK W32: Erase hidden layered windows before showing them

v3:
* Fixed a nitpick
Comment 6 Ignacio Casal Quinteiro (nacho) 2016-03-28 20:08:59 UTC
Review of attachment 324779 [details] [review]:

Fine for me. Just minor niptick with the name of the vars.

::: gdk/win32/gdkwindow-win32.c
@@ +4160,3 @@
+BOOL WINAPI
+GtkShowWindow (HWND hWnd,
+               int  nCmdShow)

cmd_show and hwnd
Comment 7 LRN 2016-03-28 20:13:02 UTC
Created attachment 324895 [details] [review]
GDK W32: Erase hidden layered windows before showing them

v4:
* Fixed a nitpick
Comment 8 Ignacio Casal Quinteiro (nacho) 2016-03-29 14:33:43 UTC
Review of attachment 324895 [details] [review]:

Fine for me.
Comment 9 LRN 2016-03-29 14:34:32 UTC
Attachment 324895 [details] pushed as 77eebbd - GDK W32: Erase hidden layered windows before showing them