Win32: Disable layered windows for GL

Layered windows and GL do not work well together, so disable layered
windows when initiating a GdkGLContext, so that GtkGLArea programs can run
properly.

Also based on patch by LRN to address the issue.

https://bugzilla.gnome.org/show_bug.cgi?id=763080
This commit is contained in:
Chun-wei Fan 2016-03-05 11:34:16 +08:00
parent 18f81d5da8
commit 3f190e0fa6
3 changed files with 43 additions and 3 deletions

View File

@ -49,6 +49,7 @@ _gdk_win32_gl_context_dispose (GObject *gobject)
GdkGLContext *context = GDK_GL_CONTEXT (gobject);
GdkWin32GLContext *context_win32 = GDK_WIN32_GL_CONTEXT (gobject);
GdkWin32Display *display_win32 = GDK_WIN32_DISPLAY (gdk_gl_context_get_display (context));
GdkWindow *window = gdk_gl_context_get_window (context);
if (context_win32->hglrc != NULL)
{
@ -63,6 +64,20 @@ _gdk_win32_gl_context_dispose (GObject *gobject)
ReleaseDC (display_win32->gl_hwnd, context_win32->gl_hdc);
}
if (window != NULL && window->impl != NULL)
{
GdkWindowImplWin32 *impl = GDK_WINDOW_IMPL_WIN32 (window->impl);
if (impl->suppress_layered > 0)
impl->suppress_layered--;
/* If we don't have any window that forces layered windows off,
* trigger update_style_bits() to enable layered windows again
*/
if (impl->suppress_layered == 0)
gdk_window_set_type_hint (window, gdk_window_get_type_hint (window));
}
G_OBJECT_CLASS (gdk_win32_gl_context_parent_class)->dispose (gobject);
}
@ -455,6 +470,9 @@ _gdk_win32_gl_context_realize (GdkGLContext *context,
gint glver_major = 0;
gint glver_minor = 0;
GdkWindow *window = gdk_gl_context_get_window (context);
GdkWindowImplWin32 *impl = GDK_WINDOW_IMPL_WIN32 (window->impl);
if (!_set_pixformat_for_hdc (context_win32->gl_hdc,
&pixel_format,
context_win32->need_alpha_bits))
@ -500,6 +518,17 @@ _gdk_win32_gl_context_realize (GdkGLContext *context,
context_win32->hglrc = hglrc;
/* OpenGL does not work with WS_EX_LAYERED enabled, so we need to
* disable WS_EX_LAYERED when we acquire a valid HGLRC
*/
impl->suppress_layered++;
/* if this is the first time a GL context is acquired for the window,
* disable layered windows by triggering update_style_bits()
*/
if (impl->suppress_layered == 1)
gdk_window_set_type_hint (window, gdk_window_get_type_hint (window));
return TRUE;
}

View File

@ -241,7 +241,6 @@ gdk_win32_window_end_paint (GdkWindow *window)
window_rect.right -= _gdk_offset_x;
window_rect.top -= _gdk_offset_y;
window_rect.bottom -= _gdk_offset_y;
if (!impl->layered)
{
GDK_NOTE (EVENTS, g_print ("Setting window position ... "));
@ -2626,9 +2625,18 @@ update_style_bits (GdkWindow *window)
/* We can get away with using layered windows
* only when no decorations are needed. It can mean
* CSD or borderless non-CSD windows (tooltips?).
*
* If this window cannot use layered windows, disable it always.
* This currently applies to windows using OpenGL, which
* does not work with layered windows.
*/
if (_gdk_win32_window_lacks_wm_decorations (window))
impl->layered = g_strcmp0 (g_getenv ("GDK_WIN32_LAYERED"), "0") != 0;
if (impl->suppress_layered == 0)
{
if (_gdk_win32_window_lacks_wm_decorations (window))
impl->layered = g_strcmp0 (g_getenv ("GDK_WIN32_LAYERED"), "0") != 0;
}
else
impl->layered = FALSE;
if (impl->layered)
new_exstyle |= WS_EX_LAYERED;

View File

@ -170,6 +170,9 @@ struct _GdkWindowImplWin32
/* Decorations set by gdk_window_set_decorations() or NULL if unset */
GdkWMDecoration* decorations;
/* No. of windows to force layered windows off */
guint suppress_layered;
};
struct _GdkWindowImplWin32Class