summaryrefslogtreecommitdiff
path: root/gdk/win32/gdkwindow-win32.c
diff options
context:
space:
mode:
authorРуслан Ижбулатов <lrn1986@gmail.com>2015-04-22 19:10:55 +0000
committerРуслан Ижбулатов <lrn1986@gmail.com>2015-04-29 21:12:13 +0000
commitd44921a152d14371dded7ce6e2c5260fd065a66b (patch)
tree772e81e341954fe3cefd925e40150786b93a3c2b /gdk/win32/gdkwindow-win32.c
parent5271106250d27e826d6cfaab095a6f66066b0c29 (diff)
downloadgtk+-d44921a152d14371dded7ce6e2c5260fd065a66b.tar.gz
Enable RGBA windows on W32
Requires Vista and newer. * Create surfaces with cairo_win32_surface_create_with_format * Provide an rgba visual that can be distinguished from the system visual * Make rgba visual the best available visual * Enable alpha-transparency for all windows that we control * Check for appropriate cairo capabilities at configure time (W32 - 1.14.3 newer than 2015-04-14; others - 1.14.0) * Check for composition support before enabling CSDs * Re-enable transparency on WM_DWMCOMPOSITIONCHANGED Windows that were created while composition was enabled and that were CSDed as a result and will look ugly (thick black borders or no borders at all) once composition is disabled. If composition is enabled afterwards, they will return back to normal. This happens, for example, when RDP session is opened to a desktop where a GTK application is running. For W7/Vista windows will only re-gain transparency after the RDP session is closed. For W8 transparency will only be gone momentarily. Windows that were created while composition was disabled will not be CSDed automatically and will use SSD (WM decorations), while windows that are CSDed manually will get a thin square border. If composition is enabled afterwards, these windows will not change. This is most noticeable for system menus (popup menus are often generated on the fly, system menus are created once) and some dialogues (About dialogue, for example). https://bugzilla.gnome.org/show_bug.cgi?id=727316
Diffstat (limited to 'gdk/win32/gdkwindow-win32.c')
-rw-r--r--gdk/win32/gdkwindow-win32.c53
1 files changed, 51 insertions, 2 deletions
diff --git a/gdk/win32/gdkwindow-win32.c b/gdk/win32/gdkwindow-win32.c
index da85ded5e2..acb475b5e9 100644
--- a/gdk/win32/gdkwindow-win32.c
+++ b/gdk/win32/gdkwindow-win32.c
@@ -41,6 +41,7 @@
#include "gdkglcontext-win32.h"
#include <cairo-win32.h>
+#include <dwmapi.h>
static void gdk_window_impl_win32_init (GdkWindowImplWin32 *window);
static void gdk_window_impl_win32_class_init (GdkWindowImplWin32Class *klass);
@@ -245,6 +246,51 @@ _gdk_windowing_window_init (GdkScreen *screen)
GDK_NOTE (MISC, g_print ("_gdk_root=%p\n", GDK_WINDOW_HWND (_gdk_root)));
}
+gboolean
+_gdk_win32_window_enable_transparency (GdkWindow *window)
+{
+ DWM_BLURBEHIND blur_behind;
+ HRGN empty_region;
+ HRESULT call_result;
+ HWND parent, thiswindow;
+
+ if (window == NULL || GDK_WINDOW_HWND (window) == NULL)
+ return FALSE;
+
+ if (!gdk_screen_is_composited (gdk_window_get_screen (window)))
+ return FALSE;
+
+ if (window == _gdk_root)
+ return FALSE;
+
+ thiswindow = GDK_WINDOW_HWND (window);
+
+ /* Blurbehind only works on toplevel windows */
+ parent = GetAncestor (thiswindow, GA_PARENT);
+ if (!(GetWindowLong (thiswindow, GWL_STYLE) & WS_POPUP) &&
+ (parent == NULL || parent != GetDesktopWindow ()))
+ return FALSE;
+
+ empty_region = CreateRectRgn (0, 0, -1, -1);
+
+ if (empty_region == NULL)
+ return FALSE;
+
+ memset (&blur_behind, 0, sizeof (blur_behind));
+ blur_behind.dwFlags = DWM_BB_ENABLE | DWM_BB_BLURREGION;
+ blur_behind.hRgnBlur = empty_region;
+ blur_behind.fEnable = TRUE;
+ call_result = DwmEnableBlurBehindWindow (thiswindow, &blur_behind);
+
+ if (!SUCCEEDED (call_result))
+ g_warning ("%s: %s (%p) failed: %" G_GINT32_MODIFIER "x",
+ G_STRLOC, "DwmEnableBlurBehindWindow", thiswindow, (guint32) call_result);
+
+ DeleteObject (empty_region);
+
+ return SUCCEEDED (call_result);
+}
+
static const gchar *
get_default_title (void)
{
@@ -490,7 +536,8 @@ _gdk_win32_display_create_window_impl (GdkDisplay *display,
window->impl = GDK_WINDOW_IMPL (impl);
if (attributes_mask & GDK_WA_VISUAL)
- g_assert (gdk_screen_get_system_visual (screen) == attributes->visual);
+ g_assert ((gdk_screen_get_system_visual (screen) == attributes->visual) ||
+ (gdk_screen_get_rgba_visual (screen) == attributes->visual));
impl->override_redirect = override_redirect;
@@ -688,6 +735,8 @@ _gdk_win32_display_create_window_impl (GdkDisplay *display,
if (attributes_mask & GDK_WA_CURSOR)
gdk_window_set_cursor (window, attributes->cursor);
+
+ _gdk_win32_window_enable_transparency (window);
}
GdkWindow *
@@ -3347,7 +3396,7 @@ gdk_win32_ref_cairo_surface (GdkWindow *window)
if (!hdc)
return NULL;
- impl->cairo_surface = cairo_win32_surface_create (hdc);
+ impl->cairo_surface = cairo_win32_surface_create_with_format (hdc, CAIRO_FORMAT_ARGB32);
cairo_surface_set_user_data (impl->cairo_surface, &gdk_win32_cairo_key,
impl, gdk_win32_cairo_surface_destroy);