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 727316 - W32: GDK does not support per-pixel alpha-blended windows
W32: GDK does not support per-pixel alpha-blended windows
Status: RESOLVED FIXED
Product: gtk+
Classification: Platform
Component: Backend: Win32
3.12.x
Other Windows
: Normal normal
: ---
Assigned To: gtk-win32 maintainers
gtk-bugs
Depends on: 741849
Blocks:
 
 
Reported: 2014-03-29 21:43 UTC by LRN
Modified: 2015-04-29 21:14 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
Adds RGBA support to W32 GDK backend (4.83 KB, patch)
2014-03-29 21:48 UTC, LRN
needs-work Details | Review
Adds cairo_win32_surface_create_with_alpha() function to cairo (3.42 KB, patch)
2014-03-29 21:49 UTC, LRN
none Details | Review
How shadows look (12.54 KB, image/png)
2014-03-29 23:19 UTC, LRN
  Details
W32: RGBA GDK backend (requires a patched version cairo) (4.96 KB, patch)
2014-04-06 15:31 UTC, LRN
none Details | Review
Misc cairo changes to make it accept RGBA formats (2.15 KB, patch)
2014-04-07 04:43 UTC, LRN
none Details | Review
A patch from cairo bug 53121, fixes crashes (1.49 KB, patch)
2014-04-07 04:44 UTC, LRN
none Details | Review
W32: Add a basic set of CSD styles (2.26 KB, patch)
2014-04-07 04:47 UTC, LRN
none Details | Review
W32: Implement composition check for GDK (4.43 KB, patch)
2014-04-10 08:52 UTC, LRN
needs-work Details | Review
W32: Implement composition check for GDK (v2) (4.39 KB, patch)
2014-04-10 09:08 UTC, LRN
none Details | Review
W32: Implement composition check for GDK (6.96 KB, patch)
2014-04-17 08:15 UTC, LRN
accepted-commit_now Details | Review
Enable RGBA windows on W32 (9.30 KB, patch)
2015-04-15 07:50 UTC, LRN
none Details | Review
Enable RGBA windows on W32 (5.69 KB, patch)
2015-04-16 23:33 UTC, LRN
none Details | Review
RGBA Window in Action on Windows (252.90 KB, image/png)
2015-04-17 11:12 UTC, Fan, Chun-wei
  Details
Enable RGBA windows on W32 (15.48 KB, patch)
2015-04-17 13:17 UTC, LRN
none Details | Review
Enable RGBA windows on W32 (15.51 KB, patch)
2015-04-17 13:55 UTC, LRN
none Details | Review
Enable RGBA windows on W32 (15.82 KB, patch)
2015-04-22 19:16 UTC, LRN
committed Details | Review
gdk: Handle W32 composition changes (5.65 KB, patch)
2015-04-28 18:41 UTC, LRN
committed Details | Review

Description LRN 2014-03-29 21:43:43 UTC
Because of this, drawing shadows around windows with CSDs does not work (windows end up with a thick black border instead of a shadow).
Comment 1 LRN 2014-03-29 21:48:17 UTC
Created attachment 273252 [details] [review]
Adds RGBA support to W32 GDK backend

This patch is broken.

Pixman will crash the process if GTK asks for padding of box-shadow for a GtkWindow, which is what happens when you do things like this:

.window-frame {
  box-shadow: 0 2px 7px 3px alpha(black, 0.8);
}

Removing the cairo_win32_surface_create_with_alpha part of the patch (using normal cairo_win32_surface_create) removes the crash, but color/alpha interpretation gets really weird (most noticeable on popup menu items).
Comment 2 LRN 2014-03-29 21:49:00 UTC
Created attachment 273253 [details] [review]
Adds cairo_win32_surface_create_with_alpha() function to cairo
Comment 3 LRN 2014-03-29 22:45:28 UTC
A backtrace of a pixman crash looks along these lines (pixman specifically compiled without SSE and MMX for debugging purposes, hence fast_composite_src_memcpy):

  • #0 msvcrt!memmove
    from C:\Windows\syswow64\msvcrt.dll
  • #1 msvcrt!memmove
    from C:\Windows\syswow64\msvcrt.dll
  • #2 fast_composite_src_memcpy
    at ../../pixman-0.32.4/pixman/pixman-fast-path.c line 1178
  • #3 pixman_image_composite32
    at ../../pixman-0.32.4/pixman/pixman.c line 707
  • #4 composite_boxes
    at ../../cairo-1.12.16/src/cairo-image-compositor.c line 533
  • #5 composite_aligned_boxes
    at ../../cairo-1.12.16/src/cairo-spans-compositor.c line 674
  • #6 clip_and_composite_boxes
    at ../../cairo-1.12.16/src/cairo-spans-compositor.c line 873
  • #7 clip_and_composite_boxes
    at ../../cairo-1.12.16/src/cairo-spans-compositor.c line 892
  • #8 _cairo_spans_compositor_paint
    at ../../cairo-1.12.16/src/cairo-spans-compositor.c line 974
  • #9 _cairo_compositor_paint
    at ../../cairo-1.12.16/src/cairo-compositor.c line 65
  • #10 _cairo_image_surface_paint
    at ../../cairo-1.12.16/src/cairo-image-surface.c line 924
  • #11 _cairo_surface_paint
    at ../../cairo-1.12.16/src/cairo-surface.c line 2031
  • #12 _cairo_surface_offset_paint
    at ../../cairo-1.12.16/src/cairo-surface-offset.c line 85
  • #13 _cairo_fallback_compositor_paint
    at ../../cairo-1.12.16/src/cairo-fallback-compositor.c line 61
  • #14 _cairo_compositor_paint
    at ../../cairo-1.12.16/src/cairo-compositor.c line 65
  • #15 _cairo_win32_display_surface_paint
    at ../../cairo-1.12.16/src/win32/cairo-win32-display-surface.c line 785
  • #16 _cairo_surface_paint
    at ../../cairo-1.12.16/src/cairo-surface.c line 2031
  • #17 _cairo_gstate_paint
    at ../../cairo-1.12.16/src/cairo-gstate.c line 1067
  • #18 cairo_paint
    at ../../cairo-1.12.16/src/cairo.c line 1999
  • #19 gdk_window_end_paint
    at ../../gtk+-3.12.0/gdk/gdkwindow.c line 2864
  • #20 gtk_main_do_event
    at ../../gtk+-3.12.0/gtk/gtkmain.c line 1648
  • #21 _gdk_event_emit
    at ../../gtk+-3.12.0/gdk/gdkevents.c line 69
  • #22 _gdk_window_process_updates_recurse_helper
    at ../../gtk+-3.12.0/gdk/gdkwindow.c line 3392
  • #23 gdk_window_process_updates_internal
    at ../../gtk+-3.12.0/gdk/gdkwindow.c line 3500
  • #24 gdk_window_process_updates_with_mode
    at ../../gtk+-3.12.0/gdk/gdkwindow.c line 3697
  • #25 _g_closure_invoke_va
    at gclosure.c line 831
  • #26 g_signal_emit_valist
    at gsignal.c line 3215
  • #27 g_signal_emit_by_name
    at gsignal.c line 3403
  • #28 gdk_frame_clock_paint_idle
    at ../../gtk+-3.12.0/gdk/gdkframeclockidle.c line 430
  • #29 gdk_threads_dispatch
    at ../../gtk+-3.12.0/gdk/gdk.c line 635
  • #30 g_timeout_dispatch
    at gmain.c line 4473
  • #31 g_main_dispatch
    at gmain.c line 3064
  • #32 g_main_context_dispatch
    at gmain.c line 3663
  • #33 g_main_context_iterate
    at gmain.c line 3734
  • #34 g_main_context_iteration
    at gmain.c line 3795
  • #35 g_application_run
    at gapplication.c line 2114
  • #36 main
    at ../../../gtk+-3.12.0/demos/widget-factory/widget-factory.c line 283

Line 1178 is:
            memcpy (dst, src, n_bytes);
The access violation comes from the attempt to access values in src. In one particular crash i've had n_bytes=3912, but src[x] gives access violation for x > 1891.
Comment 4 LRN 2014-03-29 23:12:58 UTC
Crash also goes away if i increase window frame margins considerably.
This works:
.window-frame {
  box-shadow: 0px 2px 7px 0px alpha(black, 0.8);
  margin: 18px;
}

This doesn't:
.window-frame {
  box-shadow: 0px 2px 7px 0px alpha(black, 0.8);
  margin: 17px;
}

Since margins influences the size of window frame border, input-wise (i.e. it defines, among other things, the size of the area where window can be gripped for resizing), simply increasing it is not a valid workaround, AFAIC.
Comment 5 LRN 2014-03-29 23:19:35 UTC
Created attachment 273262 [details]
How shadows look

This image is an incentive: this is what you can get with ARGB windows - sexy shadows for CSD windows (you can also get true widget transparency, but that is not very useful, while shadows are pretty much a necessity for CSD).

Also note the size of the image. It was taken by a simple Alt+PrintScreen, i.e. this is the size of the actual native W32 window. It's so big because margins is 18.
Comment 6 LRN 2014-04-06 07:16:13 UTC
Poked around a bit.
It looks like by default cairo decides to use pixman for graphics manipulations, instead of W32 API. And pixman somehow fails to notice that it is going to blit over the edge of a surface, which leads to a crash.
Forcing cairo to use W32 API doesn't work - i get the same weird alpha problems that i've had originally.
Comment 7 Ignacio Casal Quinteiro (nacho) 2014-04-06 15:03:38 UTC
Review of attachment 273252 [details] [review]:

See comments.

::: gdk/win32/gdkwindow-win32.c
@@ +705,3 @@
+
+    if (dwmEnableBlurBehindWindow)
+    {

wrong indentation here. you are missing 2 spaces

@@ +712,3 @@
+      hRgn = CreateRectRgn (0, 0, -1, -1);
+      if (hRgn != NULL)
+      {

same here
Comment 8 LRN 2014-04-06 15:31:19 UTC
Created attachment 273664 [details] [review]
W32: RGBA GDK backend (requires a patched version cairo)
Comment 9 LRN 2014-04-07 04:43:29 UTC
Created attachment 273681 [details] [review]
Misc cairo changes to make it accept RGBA formats

These may or may not have any effect on GTK. I have no idea.
Comment 10 LRN 2014-04-07 04:44:54 UTC
Created attachment 273682 [details] [review]
A patch from cairo bug 53121, fixes crashes

This patch, on the other hand, is critical to fixing crashes with RGBA windows. Taken from https://bugs.freedesktop.org/show_bug.cgi?id=53121
Comment 11 LRN 2014-04-07 04:47:02 UTC
Created attachment 273683 [details] [review]
W32: Add a basic set of CSD styles

Adds CSD styles. Goes along with RGBA windows (without it you can't see any improvements). I'd very much like to make a better-looking style for the titlebar, and maybe for window border, and definitely for the titlebar buttons, but this will suffice for now.
Comment 12 LRN 2014-04-07 06:59:04 UTC
Another thing is to make sure it doesn't go ugly when (A) no 32-bit color is set in the system, (B) DWM does not support composition (or composition is disabled). Right now, as i'm VNCing to my desktop, composition gets nuked, and window shadows once again look like thick black borders around CSDed windows.

Is there a switch in GTK that enables/disables RGBA on the fly depending on the circumstances?
Comment 13 LRN 2014-04-08 08:48:49 UTC
Well. I've always wondered why GTK CSD windows have resize-grip-areas outside of the window, where shadow is. gtkwindow.c comments cleared that up - this is intentional. Basically, GTK maintains an extra outside-of-the-window shape region that is used both for drawing a shadow and for resizing. This, by itself, is un-windowsly (normally, Windows windows have a window frame that can be gripped to resize the window; shadow is completely decorative and non-interactable, and doesn't count as part of the window as far as WM is concetned), but i'll let that slide.

The really bad consequence of this is that when desktop composition is disabled, that area outside of the window remains in use, and gtk paints it over with its default black cairo color (it's supposed to be transparent, but no composition means no transparency). Removing that region in response to a loss of composition ability is not an option, since it also prevents windows from being re-sized, because the same region is used for re-sizing. So, yeah...

One way to tackle this is to draw *something* in that region when transparency is not available. This will be ugly-ish, but not as ugly as a thick black box around a window.

The other way is to create a new GTK thingy - "is-composition-available" (or somesuch), and report availability of composition to GTK that way. If unavailable, GTK will be able to do something (such as forcing a window to not to use CSD).

I've tried doing this purely in GDK, it doesn't work (when GTK tells GDK to remove decorations, it expects the whole window to be fair game; having GDK preserve WS_BORDER style on the window has no useful effect, as GTK just draws over it).
Comment 14 Matthias Clasen 2014-04-08 15:55:24 UTC
(In reply to comment #13)

> The other way is to create a new GTK thingy - "is-composition-available" (or
> somesuch), and report availability of composition to GTK that way. If
> unavailable, GTK will be able to do something (such as forcing a window to not
> to use CSD).

See gdk_screen_is_composited(). We actally check it when deciding whether to use CSD or not. I don't think we deal well with runtime changes at the moment, though.
Comment 15 LRN 2014-04-08 17:43:48 UTC
(In reply to comment #14)
> (In reply to comment #13)
> 
> > The other way is to create a new GTK thingy - "is-composition-available" (or
> > somesuch), and report availability of composition to GTK that way. If
> > unavailable, GTK will be able to do something (such as forcing a window to not
> > to use CSD).
> 
> See gdk_screen_is_composited(). We actally check it when deciding whether to
> use CSD or not. I don't think we deal well with runtime changes at the moment,
> though.

gdk_win32_screen_is_composited() is already implemented by W32 GDK backend. It returns FALSE. This somehow does not prevent CSDs from being used.

OK, let's suppose that we will somehow fix the decision to use/not use CSDs depending on composition availability. This will make sure *new* windows will be decorated when composition is disabled. Lack of options for existing windows is kind of bad though. For example, both VNC and RDP (ssvnc client, UltraVNC server; xfreerdp client, stock MS RDP server) connections don't have composition, and managing a desktop with those will switch composition off.

This isn't the first time, i see things like that, by the way. Changing W32 themes doesn't work either (-gtk-win32-theme-part() breaks on W32 theme changes). Will GTK get support for runtime adjustments eventually? If not, then these will just go into "known bugs category".
Comment 16 LRN 2014-04-09 08:28:06 UTC
After looking at gtkwindow.c i now know why gdk_win32_screen_is_composited() has no effect. That is fixable, i'm working on a patch.

What is more interesting to me is the ability to switch client decorations on and off for already realized windows. I'll poke the code a bit more.
Comment 17 LRN 2014-04-10 08:52:34 UTC
Created attachment 273962 [details] [review]
W32: Implement composition check for GDK

Also move DWM function grabbing and make those functions available to all of GDK-Win32.
Comment 18 LRN 2014-04-10 08:57:35 UTC
Attachment 273962 [details] implements composition check in GDK and makes sure GTK actually makes use of the gdk_screen_is_composited() function.

This rolls W32 back to the state described in bug 726592: when desktop composition is not enabled, newly-created windows will not have shadows. Which means that they have no size grip (except for the optional corner grip), their rounded corners look ugly (because background is still rectangular), they blend into background because they lack shadows. And this only applies to new windows. Existing windows will just get thick black border around them, where shadow used to be.
Comment 19 Ignacio Casal Quinteiro (nacho) 2014-04-10 09:01:54 UTC
Review of attachment 273962 [details] [review]:

Here a first review.

::: gdk/win32/gdkscreen-win32.c
@@ +178,3 @@
+}
+
+

remove uneeded empty line

@@ +189,3 @@
+  /* Composition is always enabled in W8 */
+  if (major >= 6 && minor >= 2)
+    {

no need for {} in single line block

@@ +192,3 @@
+      return TRUE;
+    }
+  if (dwmIsCompositionEnabled && (S_OK == dwmIsCompositionEnabled (&b)))

leave one empty line between different ifs

@@ +193,3 @@
+    }
+  if (dwmIsCompositionEnabled && (S_OK == dwmIsCompositionEnabled (&b)))
+    {

same here
Comment 20 LRN 2014-04-10 09:08:11 UTC
Created attachment 273963 [details] [review]
W32: Implement composition check for GDK (v2)

Also move DWM function grabbing and make those functions available to all of GDK-Win32.
v2: Fixed code style
Comment 21 LRN 2014-04-10 10:51:08 UTC
So, about the bug 726592 problem for non-composited windows, i see two ways of fixing this:

(A) a non-composited version of the CSD (no shadows, just a solid/image border) 

(B) Somehow coerce GDK into enabling WM's own border for non-composited windows 
that are set to use CSDs. This looks in no way perfect, but at least it fits (or supposed to fit) half-way into native theme, and gives user something to resize the window with.

WS_SIZEBOX style looks mighty decent on a dummy test W32 app that i've made; I've had some success in replicating this to GDK, but the result doesn't look the way i expected it to, and there's a problem in differentiating appwindows from popups and tooltips.

Interesting fact: even with composition disabled, native W32 tooltips still have rounded corners and a shadow; MS probably uses 100%-layered windows for this; GDK could use that as well, but the drawing model is completely different, and it will have to be switched on and off depending on whether CSDs are enabled or disabled.
Comment 22 LRN 2014-04-10 14:55:39 UTC
And the final nitpick is that rounded window corners should be eliminated for toplevels when there's no composition. Because it inherently requires transparent windows.

Not sure how to do that; expose non-composited state to CSS (and have a separate style for non-composited windows), or do it in code? What about themes that draw titlebar background/border from images? Only css that invokes an image in the first place knows whether it has rounded corners or not.

Also, another fact: GTK tooltips (with background drawn by -gtk-win32-theme-part) also retain their rounded corners when composition is disabled (although the corners are visibly not as smooth as when composition is enabled; also, top-right and bottom-right corners may initially appear to be black, until mouse is moved a bit).
Comment 23 LRN 2014-04-17 07:52:19 UTC
IRC conversations with GTK+ devs (namely - Company) left me with this statement: GKT+-3.x is aimed at desktops that support composition. If they don't, it's ok for GTK+-3.x to look ugly.

Which led to a question: just how often is composition off on Windows?

Some people (including myself) readily pointed out that VNCing and RDPing into W7 desktop switches composition off.

After googling a bit and doing some tests i've found that only RDP servers in server editions of W7 (and W2008) support desktop composition (and even then you need to actively enable it via policy or by editing the registry).

With VNC things are a bit better: UltraVNC does not disable composition in W7, unless mirror driver is being used.

W8, on the other hand, has desktop composition enabled all the time, and my tests confirm that neither VNC nor RDP connecting to a W8 desktop have any effect on composition (but then, W8 has neither window shadows nor transparent window frames, so the difference is difficult to see; taskbar is transparent though).

So, apart from the problem with non-server versions of Windows and RDP, composition on W7 is pretty much a given, and on W8 is guaranteed.

To that end i take back the requirement for GTK+ to do anything on composition on/off switching.
Comment 24 LRN 2014-04-17 08:15:18 UTC
Created attachment 274579 [details] [review]
W32: Implement composition check for GDK

Also move DWM function grabbing and make those functions available to all of GDK-Win32.

v2: Fixed code style
v3: Added a missing part of the patch (where stuff from attachment 273664 [details] [review] is partially removed)
Comment 25 Matthias Clasen 2014-04-23 03:41:02 UTC
Review of attachment 274579 [details] [review]:

this patch look to me, but it depends on making rgba actually work (ie the other patches in this bug), since the docs say:

 * Returns whether windows with an RGBA visual can reasonably
 * be expected to have their alpha channel drawn correctly on
 * the screen.
Comment 26 Matthias Clasen 2014-04-23 03:43:38 UTC
Review of attachment 273683 [details] [review]:

ok
Comment 27 LRN 2014-04-23 05:42:36 UTC
A small correction for comment 23:
RDPing into a W8 desktop (non-server OS) does not disable desktop composition, but it does induce some kind of mode switch that breaks the rendering of existing GDK windows the same way disabling composition does. So there is some room for W32-GDK improvement.

Anyway, things are now blocked on cairo being fixed, and that is not going very well: cairo devs point out that existing workaround is, in fact, a workaround, not a fix, but at the same time i can't fix cairo myself properly, and cairo doesn't seem to have a living-and-breathing w32 maintainer either.
Comment 28 Sandro Mani 2014-05-02 19:48:37 UTC
Might it be possible to revert the previous behaviour for Windows until this is fixed?
Comment 29 LRN 2014-10-14 07:17:45 UTC
With cairo 1.14.0 things improved somewhat: the bug that caused it to crash with transparent windows *seems* to be fixed (i've done limited testing so far; can't be sure until i do a clean rebuild). It still needs patches for RGBA windows to be enabled (i.e. the cairo_win32_surface_create_with_alpha() at the very least, or its equivalent), but these should be much less controversial than the patch from https://bugs.freedesktop.org/show_bug.cgi?id=53121 .
Comment 30 Fan, Chun-wei 2014-12-22 09:16:17 UTC
Hi,

Just wondering, since we also want to check for whether we have composition for the GdkScreen when we do OpenGL, can we try to get the composition stuff into GDK-Win32, and make that as a prerequisite of this instead?  I will open another bug for this[1], or we can re-use parts of LRN's work for this, depending on whether it is preferable that way.

With blessings, thank you!

[1]: Bug 741849
Comment 31 LRN 2015-04-15 07:50:31 UTC
Created attachment 301594 [details] [review]
Enable RGBA windows on W32

\o/ cairo devs finally accepted my patch - http://cgit.freedesktop.org/cairo/commit/?id=16898ba11b4d6e9e2e64bb2d02d0fb5adbe266e2

This new patch combines rgba window creation, composition check, dwm stuff and the no-transparency-for-childwindows fixup.

Also obsoleting old cairo patches that no longer apply.
Comment 32 Fan, Chun-wei 2015-04-15 07:57:58 UTC
Yay!  Great to hear this!
Comment 33 Ignacio Casal Quinteiro (nacho) 2015-04-15 07:59:00 UTC
Review of attachment 301594 [details] [review]:

See comments.

::: gdk/win32/gdkscreen-win32.c
@@ +199,3 @@
+  BOOL enabled;
+#endif
+  DWORD sysver, major, minor;

I think fan added a method in glib for the version stuff, since afaik GetVersion is deprecated?

::: gdk/win32/gdkwindow-win32.c
@@ +706,3 @@
+ */
+#ifdef HAVE_W32_DWM
+  if (suitable_for_alpha && \

why the \? that is not needed

@@ +3390,3 @@
 	return NULL;
 
+      impl->cairo_surface =

just put it in one line
Comment 34 Fan, Chun-wei 2015-04-15 10:04:55 UTC
Review of attachment 301594 [details] [review]:

Hi,

The function in GLib to check the version stuff is g_win32_check_windows_version(), which also handles post Windows 8.1 fine, since GetVersion()/GetVersionEx() is deprecated by Microsoft.

I think, as I mentioned in bug 741849, I think it's time that we just start to forget about having the code run on Windows XP, as AFAIK we are dropping XP support in this dev cycle, and Emmanuele is getting GSK in, which depends on his graphene library, which does not run on XP.

With blessings.
Comment 35 LRN 2015-04-16 23:33:41 UTC
Created attachment 301766 [details] [review]
Enable RGBA windows on W32

Rebased on top of patches from bug 741849

Requires Vista and newer (same as bug 741849).
Requires cairo-1.14.4 (or 1.14.3 past 2015-04-14). I found no way to make this requirement variable and require 1.14.4 only on W32.
Comment 36 Ignacio Casal Quinteiro (nacho) 2015-04-17 06:25:38 UTC
Review of attachment 301766 [details] [review]:

Patch looks good to me. See the nitpick. If fan or mclasen give the ack I'd say go for it.

::: gdk/win32/gdkwindow-win32.c
@@ +716,3 @@
+    {
+      g_warning ("%s: %s failed: %" G_GINT32_MODIFIER "x",
+          G_STRLOC, "DwmEnableBlurBehindWindow", (guint32) call_result);

align this and no need for the {} in single calls
Comment 37 Alexander Larsson 2015-04-17 10:20:55 UTC
Review of attachment 301766 [details] [review]:

::: gdk/win32/gdkscreen-win32.c
@@ +238,3 @@
   screen_class->get_monitor_workarea = gdk_win32_screen_get_monitor_geometry;
   screen_class->get_system_visual = _gdk_win32_screen_get_system_visual;
+  screen_class->get_rgba_visual = _gdk_win32_screen_get_system_visual;

I'm not sure this is quite right. I think you want two different visuals. One with alpha and one without. That way you know if the app explicitly chose alpha or not.
Comment 38 Fan, Chun-wei 2015-04-17 11:12:16 UTC
Created attachment 301812 [details]
RGBA Window in Action on Windows

Hi LRN,

I checked the build in both x64 (the css basics with the text in red (2008) and purple (2013)) and x86 (the css basics with the text in brown), going into checking how things go.  Generally I think things look good (especially if the css basic image is like what you intended it to be).

Thanks very much for venturing into this, and this also gets the GtkGLArea support on Windows more feature-complete.

With blessings.
Comment 39 LRN 2015-04-17 13:17:19 UTC
Created attachment 301835 [details] [review]
Enable RGBA windows on W32

* Added a separate rgba visual.
* Fixed an assertion that checks for visuals to pass with the rgba visual
* Modified the configure cairo check. Now it again checks for 1.14.0,
  but then goes on to make a special followup check on W32, looking
  for cairo_win32_surface_create_with_format() and failing if it's absent.
Comment 40 LRN 2015-04-17 13:55:49 UTC
Created attachment 301842 [details] [review]
Enable RGBA windows on W32

*Fixed nitpicks
Comment 41 LRN 2015-04-22 19:16:44 UTC
Created attachment 302176 [details] [review]
Enable RGBA windows on W32

* 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
* Check for composition support before enabling CSDs
* 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)

Requires Vista and newer.
Comment 42 Alexander Larsson 2015-04-27 14:18:15 UTC
Review of attachment 302176 [details] [review]:

::: gdk/win32/gdkwindow-win32.c
@@ +3378,3 @@
 	return NULL;
 
+      impl->cairo_surface = cairo_win32_surface_create_with_format (hdc, CAIRO_FORMAT_ARGB32);

I think this should be RGB24 if the visual is not the rgba visual, no?

::: gtk/gtkwindow.c
@@ +3981,3 @@
 
+      if (!gdk_screen_is_composited (screen))
+        return FALSE;

Is the screen ever composited on win32?
Comment 43 Alexander Larsson 2015-04-27 14:18:16 UTC
Review of attachment 302176 [details] [review]:

::: gdk/win32/gdkwindow-win32.c
@@ +3378,3 @@
 	return NULL;
 
+      impl->cairo_surface = cairo_win32_surface_create_with_format (hdc, CAIRO_FORMAT_ARGB32);

I think this should be RGB24 if the visual is not the rgba visual, no?

::: gtk/gtkwindow.c
@@ +3981,3 @@
 
+      if (!gdk_screen_is_composited (screen))
+        return FALSE;

Is the screen ever composited on win32?
Comment 44 LRN 2015-04-27 15:22:35 UTC
(In reply to Alexander Larsson from comment #42)
> Review of attachment 302176 [details] [review] [review]:
> 
> ::: gdk/win32/gdkwindow-win32.c
> @@ +3378,3 @@
>  	return NULL;
>  
> +      impl->cairo_surface = cairo_win32_surface_create_with_format (hdc,
> CAIRO_FORMAT_ARGB32);
> 
> I think this should be RGB24 if the visual is not the rgba visual, no?

Depends on what cairo thinks ARGB32 is. If it's just an A channel attached to RGB channels, we have nothing to worry about. GDI will just ignore or garble the A channel and use RGB. If it's some kind of pre-multiplied alpha, then parts that cairo thought were to be transparent are going to be just...pale...

Yep, looked it up - cairo uses pre-multiplied alpha. Nice. OK, i'll look into it.

> 
> ::: gtk/gtkwindow.c
> @@ +3981,3 @@
>  
> +      if (!gdk_screen_is_composited (screen))
> +        return FALSE;
> 
> Is the screen ever composited on win32?

Yes. Wait, you haven't read the comments on this bug or bug 741849 ?
Comment 45 LRN 2015-04-28 03:12:56 UTC
Problem: alpha window (from testgtk) has b0rked contents on 8.1 (but looks OK on 7).

However, forcing alpha window to use CSDs magically solves the problem.

Still investigating the cause.

Some good news: i think i can make transparent windows become transparent again after composition was disabled and re-enabled for some reason. This requires handling WM_DWMCOMPOSITIONCHANGED message by re-enabling blurbehind for a window.
Comment 46 LRN 2015-04-28 13:17:02 UTC
Some person on stackoverflow says that blurbehind does not, in fact, blur anything anymore in 8, and that the only way to draw transparent windows the "usual" way now is to properly use layered windows. Great.
I also found a weird blogpost[1] about drawing windows without using a redirection surface. AFAIU, this is 100% DirectX-based.

I'll try to dig the layered windows angle a bit more.

[1] https://msdn.microsoft.com/en-us/magazine/dn745861.aspx
Comment 47 Matthias Clasen 2015-04-28 13:26:27 UTC
thanks for the continued investigation!
Comment 48 Fan, Chun-wei 2015-04-28 14:46:30 UTC
Hi,

(In reply to LRN from comment #46)
> Some person on stackoverflow says that blurbehind does not, in fact, blur
> anything anymore in 8,

I think the reason behind this is that Aero Glass has been removed on Windows 8, plus this functionality is not available on the Starter and Home Basic Editions of Windows Vista/7.[a]

> and that the only way to draw transparent windows the
> "usual" way now is to properly use layered windows. Great.
> I also found a weird blogpost[1] about drawing windows without using a
> redirection surface. AFAIU, this is 100% DirectX-based.
> 
> I'll try to dig the layered windows angle a bit more.

Perhaps, I think for now, is to get this item in with a TODO note indicating that this need to be further investigated for Windows 8.x, which would mean another bug for that.  I'm not sure how many people use Vista (or 7) Starter or Home Basic with GTK+-3.x, but most likely tackling Windows 8.x will also tackle the more entry-level editions of Windows.

[a]: https://msdn.microsoft.com/en-us/library/windows/desktop/aa969537%28v=vs.85%29.aspx

With blessings, thanks!
Comment 49 Fan, Chun-wei 2015-04-28 15:02:51 UTC
Hi LRN,

Would this code project page help you for Windows 8+?

http://www.codeproject.com/Articles/705243/HUD-window-bit-DWM-composition

With blessings!
Comment 50 LRN 2015-04-28 15:36:36 UTC
(In reply to Fan, Chun-wei from comment #49)
> Would this code project page help you for Windows 8+?
> 
> http://www.codeproject.com/Articles/705243/HUD-window-bit-DWM-composition
> 
Codeproject programs should be handled with care, as they are non-free (CPOL license). I don't know whether that applies to the source code only or to the contents of the associated blogpost as well.

(In reply to Fan, Chun-wei from comment #48)
> Hi,
> 
> (In reply to LRN from comment #46)
> > Some person on stackoverflow says that blurbehind does not, in fact, blur
> > anything anymore in 8,
> 
> I think the reason behind this is that Aero Glass has been removed on
> Windows 8, plus this functionality is not available on the Starter and Home
> Basic Editions of Windows Vista/7.[a]

Could be. However, Windows 8 still does support transparent windows (taskbar is transparent in Windows 8, for example). Maybe they just use a different rendering mechanism... Also, CSDed GTK windows are rendered just fine on Windows 8, only the gtktest alphawindow (which is the first and the one only of its kind that i've ever seen - a GTK window that has WM decorations *and* transparent contents) has problems. I still haven't figured why. My attempts to reproduce this in a simple non-GTK testcase were unsuccessful.

> 
> > and that the only way to draw transparent windows the
> > "usual" way now is to properly use layered windows. Great.
> > I also found a weird blogpost[1] about drawing windows without using a
> > redirection surface. AFAIU, this is 100% DirectX-based.
> > 
> > I'll try to dig the layered windows angle a bit more.
> 
> Perhaps, I think for now, is to get this item in with a TODO note indicating
> that this need to be further investigated for Windows 8.x, which would mean
> another bug for that.  I'm not sure how many people use Vista (or 7) Starter
> or Home Basic with GTK+-3.x, but most likely tackling Windows 8.x will also
> tackle the more entry-level editions of Windows.
> 

I'd say we need to figure out just how many GTK apps do transparent client area with WM decorations. If gtktest alphawindow is the only one, then fixing this is not a priority, and we can just put this into a list of known bugs for now.

Change of the rendering process (from WM_PAINT to UpdateLayeredWindow) is long overdue, but can be done in a new bug. Bug 272316 is for "fix transparency with the tools at hand", not the "rewrite gdk-w32 rendering system".
Comment 51 LRN 2015-04-28 15:52:56 UTC
LRN:		gtk devs. Question: how many apps actually use transparent contents (where desktop or other windows can be seen through)?
LRN:		Followup: how many of these apps do that without also enabling CSD?
mclasen:	LRN: only gnome-terminal, with a downstream patch
LRN:		mclasen, in that case we'll push bug 727316 as-is (well, i have an unrelated followup, but that doesn't matter) and make the remaining W8 problems into a KnownBug
nacho:		LRN, so for 8+ csd will not work?
LRN:	 nacho, CSD will work, transparent windows without CSD won't
nacho:		ah! ok
nacho:		I guess that's fine
mclasen:	LRN: sounds good to me
Comment 52 Fan, Chun-wei 2015-04-28 16:14:32 UTC
Hello LRN,

(In reply to LRN from comment #51)
> nacho:		I guess that's fine
> mclasen:	LRN: sounds good to me

Sounds good to me as well-especially that not so many people use Windows 8+, relatively speaking.

With blessings.

p.s. The CodeProject part, it was more on the blog for future references (I don't think CPOL would hit that part that much, though).  Sorry for my not-too-clear wording.
Comment 53 LRN 2015-04-28 18:41:27 UTC
Created attachment 302526 [details] [review]
gdk: Handle W32 composition changes

This change allows alpha-blended windows to suffer through composition
being disabled and come out of it in one piece.
Comment 54 LRN 2015-04-28 18:45:11 UTC
Fanc, please do a final review of everything. If everything's all right, i'll push the code changes.

Attachment 273683 [details] will probably remain unpushed, since it's kind of half-baked, and also old. I don't do much for the Windows theme anymore, given that Adwaita is the default, so improving it is not on my TODO list.
Comment 55 Fan, Chun-wei 2015-04-29 00:47:19 UTC
Review of attachment 302526 [details] [review]:

Hi LRN,

I think we are good to go for these 2 patches (that is, attachments 302176 and 302526), but I'd guess that it would be best if we squash them as 302526 depends on 302176, if it's ok to you.

With blessings, thank you!
Comment 56 Fan, Chun-wei 2015-04-29 07:01:34 UTC
Hi LRN,

...oh, and can you please also change the #define WINVER 0x0500 to #define WINVER 0x0600 in gdkprivate-win32.h so that we can be sure that everything can be found from the Windows headers, such as WM_DWMCOMPOSITIONCHANGED, as they require _WIN32_WINNT to be at least 0x0600 so that they can be found during the build.

For attachment 302526 [details] [review] (as you squash them), I think there are some trailing white spaces in there, so please also get rid of them.

With blessings, thank you!
Comment 57 LRN 2015-04-29 21:14:36 UTC
Attachment 302176 [details] pushed as d44921a - Enable RGBA windows on W32
Attachment 302526 [details] squashed into it