summaryrefslogtreecommitdiff
path: root/gdk
diff options
context:
space:
mode:
authorРуслан Ижбулатов <lrn1986@gmail.com>2016-03-16 18:16:33 +0000
committerРуслан Ижбулатов <lrn1986@gmail.com>2016-03-29 14:36:09 +0000
commit884adaac9ec5b917d6516f2f2f23d77432a1c563 (patch)
tree6fc7975b0709aa61432ade037b70a77fcece937b /gdk
parentff93dfd3eb51376f2815cc215b9997113d1c50ac (diff)
downloadgtk+-884adaac9ec5b917d6516f2f2f23d77432a1c563.tar.gz
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. https://bugzilla.gnome.org/show_bug.cgi?id=763783
Diffstat (limited to 'gdk')
-rw-r--r--gdk/win32/gdkevents-win32.c6
-rw-r--r--gdk/win32/gdkprivate-win32.h3
-rw-r--r--gdk/win32/gdkwindow-win32.c107
3 files changed, 97 insertions, 19 deletions
diff --git a/gdk/win32/gdkevents-win32.c b/gdk/win32/gdkevents-win32.c
index 1f802af1a8..3ed2840f0d 100644
--- a/gdk/win32/gdkevents-win32.c
+++ b/gdk/win32/gdkevents-win32.c
@@ -1053,17 +1053,17 @@ show_window_recurse (GdkWindow *window, gboolean hide_window)
{
if (gdk_window_get_state (window) & GDK_WINDOW_STATE_MAXIMIZED)
{
- ShowWindow (GDK_WINDOW_HWND (window), SW_SHOWMAXIMIZED);
+ GtkShowWindow (GDK_WINDOW_HWND (window), SW_SHOWMAXIMIZED);
}
else
{
- ShowWindow (GDK_WINDOW_HWND (window), SW_RESTORE);
+ GtkShowWindow (GDK_WINDOW_HWND (window), SW_RESTORE);
}
}
}
else
{
- ShowWindow (GDK_WINDOW_HWND (window), SW_MINIMIZE);
+ GtkShowWindow (GDK_WINDOW_HWND (window), SW_MINIMIZE);
}
}
diff --git a/gdk/win32/gdkprivate-win32.h b/gdk/win32/gdkprivate-win32.h
index b3f89d3ff9..5be53abb8a 100644
--- a/gdk/win32/gdkprivate-win32.h
+++ b/gdk/win32/gdkprivate-win32.h
@@ -537,6 +537,9 @@ gboolean _gdk_win32_window_fill_min_max_info (GdkWindow *window,
gboolean _gdk_win32_window_lacks_wm_decorations (GdkWindow *window);
+BOOL WINAPI GtkShowWindow (HWND hwnd,
+ int cmd_show);
+
/* Initialization */
void _gdk_win32_windowing_init (void);
void _gdk_dnd_init (void);
diff --git a/gdk/win32/gdkwindow-win32.c b/gdk/win32/gdkwindow-win32.c
index bedf5351ea..d2d0be5235 100644
--- a/gdk/win32/gdkwindow-win32.c
+++ b/gdk/win32/gdkwindow-win32.c
@@ -1145,7 +1145,7 @@ show_window_internal (GdkWindow *window,
!already_mapped &&
(window->state & GDK_WINDOW_STATE_ICONIFIED))
{
- ShowWindow (GDK_WINDOW_HWND (window), SW_SHOWMINNOACTIVE);
+ GtkShowWindow (GDK_WINDOW_HWND (window), SW_SHOWMINNOACTIVE);
return;
}
@@ -1318,29 +1318,29 @@ show_window_internal (GdkWindow *window,
}
else if (window->state & GDK_WINDOW_STATE_MAXIMIZED)
{
- ShowWindow (GDK_WINDOW_HWND (window), SW_MAXIMIZE);
+ GtkShowWindow (GDK_WINDOW_HWND (window), SW_MAXIMIZE);
}
else if (window->state & GDK_WINDOW_STATE_ICONIFIED)
{
if (focus_on_map)
- ShowWindow (GDK_WINDOW_HWND (window), SW_RESTORE);
+ GtkShowWindow (GDK_WINDOW_HWND (window), SW_RESTORE);
else
- ShowWindow (GDK_WINDOW_HWND (window), SW_SHOWNOACTIVATE);
+ GtkShowWindow (GDK_WINDOW_HWND (window), SW_SHOWNOACTIVATE);
}
else if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_TEMP || !focus_on_map)
{
if (!IsWindowVisible (GDK_WINDOW_HWND (window)))
- ShowWindow (GDK_WINDOW_HWND (window), SW_SHOWNOACTIVATE);
+ GtkShowWindow (GDK_WINDOW_HWND (window), SW_SHOWNOACTIVATE);
else
- ShowWindow (GDK_WINDOW_HWND (window), SW_SHOWNA);
+ GtkShowWindow (GDK_WINDOW_HWND (window), SW_SHOWNA);
}
else if (!IsWindowVisible (GDK_WINDOW_HWND (window)))
{
- ShowWindow (GDK_WINDOW_HWND (window), SW_SHOWNORMAL);
+ GtkShowWindow (GDK_WINDOW_HWND (window), SW_SHOWNORMAL);
}
else
{
- ShowWindow (GDK_WINDOW_HWND (window), SW_SHOW);
+ GtkShowWindow (GDK_WINDOW_HWND (window), SW_SHOW);
}
/* Sync STATE_ABOVE to TOPMOST */
@@ -1395,7 +1395,7 @@ gdk_win32_window_hide (GdkWindow *window)
}
else
{
- ShowWindow (GDK_WINDOW_HWND (window), SW_HIDE);
+ GtkShowWindow (GDK_WINDOW_HWND (window), SW_HIDE);
}
}
@@ -3415,7 +3415,7 @@ gdk_win32_window_iconify (GdkWindow *window)
if (GDK_WINDOW_IS_MAPPED (window))
{
old_active_window = GetActiveWindow ();
- ShowWindow (GDK_WINDOW_HWND (window), SW_MINIMIZE);
+ GtkShowWindow (GDK_WINDOW_HWND (window), SW_MINIMIZE);
if (old_active_window != GDK_WINDOW_HWND (window))
SetActiveWindow (old_active_window);
}
@@ -3486,7 +3486,7 @@ gdk_win32_window_maximize (GdkWindow *window)
_gdk_win32_window_state_to_string (window->state)));
if (GDK_WINDOW_IS_MAPPED (window))
- ShowWindow (GDK_WINDOW_HWND (window), SW_MAXIMIZE);
+ GtkShowWindow (GDK_WINDOW_HWND (window), SW_MAXIMIZE);
else
gdk_synthesize_window_state (window,
0,
@@ -3506,7 +3506,7 @@ gdk_win32_window_unmaximize (GdkWindow *window)
_gdk_win32_window_state_to_string (window->state)));
if (GDK_WINDOW_IS_MAPPED (window))
- ShowWindow (GDK_WINDOW_HWND (window), SW_RESTORE);
+ GtkShowWindow (GDK_WINDOW_HWND (window), SW_RESTORE);
else
gdk_synthesize_window_state (window,
GDK_WINDOW_STATE_MAXIMIZED,
@@ -3658,13 +3658,13 @@ gdk_win32_window_focus (GdkWindow *window,
_gdk_win32_window_state_to_string (window->state)));
if (window->state & GDK_WINDOW_STATE_MAXIMIZED)
- ShowWindow (GDK_WINDOW_HWND (window), SW_SHOWMAXIMIZED);
+ GtkShowWindow (GDK_WINDOW_HWND (window), SW_SHOWMAXIMIZED);
else if (window->state & GDK_WINDOW_STATE_ICONIFIED)
- ShowWindow (GDK_WINDOW_HWND (window), SW_RESTORE);
+ GtkShowWindow (GDK_WINDOW_HWND (window), SW_RESTORE);
else if (!IsWindowVisible (GDK_WINDOW_HWND (window)))
- ShowWindow (GDK_WINDOW_HWND (window), SW_SHOWNORMAL);
+ GtkShowWindow (GDK_WINDOW_HWND (window), SW_SHOWNORMAL);
else
- ShowWindow (GDK_WINDOW_HWND (window), SW_SHOW);
+ GtkShowWindow (GDK_WINDOW_HWND (window), SW_SHOW);
SetFocus (GDK_WINDOW_HWND (window));
}
@@ -4157,6 +4157,81 @@ gdk_win32_ref_cairo_surface (GdkWindow *window)
return impl->cairo_surface;
}
+BOOL WINAPI
+GtkShowWindow (HWND hwnd,
+ int cmd_show)
+{
+ cairo_t *cr;
+ cairo_surface_t *surface;
+ RECT window_rect;
+ HDC hdc;
+ POINT window_position;
+ SIZE window_size;
+ POINT source_point;
+ BLENDFUNCTION blender;
+
+ switch (cmd_show)
+ {
+ case SW_FORCEMINIMIZE:
+ case SW_HIDE:
+ case SW_MINIMIZE:
+ break;
+ case SW_MAXIMIZE:
+ case SW_RESTORE:
+ case SW_SHOW:
+ case SW_SHOWDEFAULT:
+ case SW_SHOWMINIMIZED:
+ case SW_SHOWMINNOACTIVE:
+ case SW_SHOWNA:
+ case SW_SHOWNOACTIVATE:
+ case SW_SHOWNORMAL:
+ if (IsWindowVisible (hwnd))
+ break;
+
+ if ((WS_EX_LAYERED & GetWindowLongPtr (hwnd, GWL_EXSTYLE)) != WS_EX_LAYERED)
+ break;
+
+ /* Window was hidden, will be shown. Erase it, GDK will repaint soon,
+ * but not soon enough, so it's possible to see old content before
+ * the next redraw, unless we erase the window first.
+ */
+ GetWindowRect (hwnd, &window_rect);
+ source_point.x = source_point.y = 0;
+
+ window_position.x = window_rect.left;
+ window_position.y = window_rect.top;
+ window_size.cx = window_rect.right - window_rect.left;
+ window_size.cy = window_rect.bottom - window_rect.top;
+
+ blender.BlendOp = AC_SRC_OVER;
+ blender.BlendFlags = 0;
+ blender.AlphaFormat = AC_SRC_ALPHA;
+ blender.SourceConstantAlpha = 255;
+
+ /* Create a surface of appropriate size and clear it */
+ surface = cairo_win32_surface_create_with_dib (CAIRO_FORMAT_ARGB32, window_size.cx, window_size.cy);
+ cr = cairo_create (surface);
+ cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+ cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 0.0);
+ cairo_paint (cr);
+ cairo_destroy (cr);
+ cairo_surface_flush (surface);
+ hdc = cairo_win32_surface_get_dc (surface);
+
+ /* No API_CALL() wrapper, don't check for errors */
+ UpdateLayeredWindow (hwnd, NULL,
+ &window_position, &window_size,
+ hdc, &source_point,
+ 0, &blender, ULW_ALPHA);
+
+ cairo_surface_destroy (surface);
+
+ break;
+ }
+
+ return ShowWindow (hwnd, cmd_show);
+}
+
static void
gdk_window_impl_win32_class_init (GdkWindowImplWin32Class *klass)
{