[mono/mono] [2 commits] 6c620c74: X11: improve handling of WS_EX_TOPMOST

"alexrp ([email protected])" <[email protected]>
Newsgroups gmane.comp.gnome.mono.patches
Message-ID <00000141dc410954-60461d23-df76-47a0-90f7-7054cba94800-000000@email.amazonses.com>
   Branch: refs/heads/master
     Home: https://github.com/mono/mono
  Compare: https://github.com/mono/mono/compare/b86af4848657...e946a6cdebde

   Commit: 6c620c74f32908a5875c2b53f44e0b297a6a7b73
   Author: Peter Collingbourne <[email protected]> (pcc)
     Date: 2012-04-09 01:22:37 GMT
      URL: https://github.com/mono/mono/commit/6c620c74f32908a5875c2b53f44e0b297a6a7b73

X11: improve handling of WS_EX_TOPMOST

Currently, WS_EX_TOPMOST is handled by making the window transient-for
the root window.  I was unable to find any documentation that indicated
that this would have the desired effect.  Instead, use SetTopmost to
set _NET_WM_STATE to _NET_WM_STATE_ABOVE, per EWMH.

Also, use XMapRaised to raise topmost windows to the top of the stack
when mapped, as a last ditch effort to support window managers that
do not respect _NET_WM_STATE, such as xmonad.

This fixes an issue I encountered when running a winforms application
in xmonad, whereby drop down menus would fail to re-open if windows
had been re-arranged after the menu was first opened (in reality,
the menu was hiding behind the form).

Changed paths:
  M mcs/class/Managed.Windows.Forms/System.Windows.Forms/Hwnd.cs
  M mcs/class/Managed.Windows.Forms/System.Windows.Forms/XplatUIX11.cs

Modified: mcs/class/Managed.Windows.Forms/System.Windows.Forms/Hwnd.cs
===================================================================
@@ -76,6 +76,7 @@ internal class Hwnd : IDisposable {
 		internal bool		whacky_wm;
 		internal bool		fixed_size;
 		internal bool		zombie; /* X11 only flag.  true if the X windows have been destroyed but we haven't been Disposed */
+		internal bool		topmost; /* X11 only. */
 		internal Region		user_clip;
 		internal XEventQueue	queue;
 		internal WindowExStyles	initial_ex_style;
@@ -122,6 +123,7 @@ internal class Hwnd : IDisposable {
 			children = new ArrayList ();
 			resizing_or_moving = false;
 			whacky_wm = false;
+			topmost = false;
 		}
 
 		public void Dispose() {

Modified: mcs/class/Managed.Windows.Forms/System.Windows.Forms/XplatUIX11.cs
===================================================================
@@ -1603,11 +1603,23 @@ static Hwnd.Borders FrameExtents (IntPtr window)
 				if (hwnd.zombie)
 					return;
 
-				if ((windows & WindowType.Whole) != 0) {
-					XMapWindow(DisplayHandle, hwnd.whole_window);
-				}
-				if ((windows & WindowType.Client) != 0) {
-					XMapWindow(DisplayHandle, hwnd.client_window);
+				if (hwnd.topmost) {
+					// Most window managers will respect the _NET_WM_STATE property.
+					// If not, use XMapRaised to map the window at the top level as
+					// a last ditch effort.
+					if ((windows & WindowType.Whole) != 0) {
+						XMapRaised(DisplayHandle, hwnd.whole_window);
+					}
+					if ((windows & WindowType.Client) != 0) {
+						XMapRaised(DisplayHandle, hwnd.client_window);
+					}
+				} else {
+					if ((windows & WindowType.Whole) != 0) {
+						XMapWindow(DisplayHandle, hwnd.whole_window);
+					}
+					if ((windows & WindowType.Client) != 0) {
+						XMapWindow(DisplayHandle, hwnd.client_window);
+					}
 				}
 
 				hwnd.mapped = true;
@@ -2937,13 +2949,8 @@ internal override IntPtr CreateWindow (CreateParams cp)
 					XSelectInput(DisplayHandle, hwnd.client_window, new IntPtr ((int)(SelectInputMask | EventMask.StructureNotifyMask | Keyboard.KeyEventMask)));
 			}
 
-			if (ExStyleSet (cp.ExStyle, WindowExStyles.WS_EX_TOPMOST)) {
-				atoms = new int[2];
-				atoms[0] = _NET_WM_WINDOW_TYPE_NORMAL.ToInt32();
-				XChangeProperty(DisplayHandle, hwnd.whole_window, _NET_WM_WINDOW_TYPE, (IntPtr)Atom.XA_ATOM, 32, PropertyMode.Replace, atoms, 1);
-
-				XSetTransientForHint (DisplayHandle, hwnd.whole_window, RootWindow);
-			}
+			if (ExStyleSet (cp.ExStyle, WindowExStyles.WS_EX_TOPMOST))
+				SetTopmost(hwnd.whole_window, true);
 
 			SetWMStyles(hwnd, cp);
 			
@@ -5748,6 +5755,7 @@ internal override bool SetTopmost(IntPtr handle, bool enabled)
 		{
 
 			Hwnd hwnd = Hwnd.ObjectFromHandle(handle);
+			hwnd.topmost = enabled;
 
 			if (enabled) {
 				lock (XlibLock) {
@@ -6366,6 +6374,13 @@ internal static int XMapWindow(IntPtr display, IntPtr window)
 			DebugHelper.TraceWriteLine ("XMapWindow");
 			return _XMapWindow(display, window);
 		}
+		[DllImport ("libX11", EntryPoint="XMapRaised")]
+		internal extern static int _XMapRaised(IntPtr display, IntPtr window);
+		internal static int XMapRaised(IntPtr display, IntPtr window)
+		{
+			DebugHelper.TraceWriteLine ("XMapRaised");
+			return _XMapRaised(display, window);
+		}
 		[DllImport ("libX11", EntryPoint="XUnmapWindow")]
 		internal extern static int _XUnmapWindow(IntPtr display, IntPtr window);
 		internal static int XUnmapWindow(IntPtr display, IntPtr window)
@@ -7216,6 +7231,9 @@ internal static void XIfEvent (IntPtr display, ref XEvent xevent, Delegate event
 		[DllImport ("libX11", EntryPoint="XMapWindow")]
 		internal extern static int XMapWindow(IntPtr display, IntPtr window);
 		
+		[DllImport ("libX11", EntryPoint="XMapRaised")]
+		internal extern static int XMapRaised(IntPtr display, IntPtr window);
+		
 		[DllImport ("libX11", EntryPoint="XUnmapWindow")]
 		internal extern static int XUnmapWindow(IntPtr display, IntPtr window);
 		

   Commit: e946a6cdebde729e1c03ec374184254ab38da184
   Author: Alex Rønne Petersen <[email protected]> (alexrp)
     Date: 2013-10-21 18:19:47 GMT
      URL: https://github.com/mono/mono/commit/e946a6cdebde729e1c03ec374184254ab38da184

Merge pull request #260 from pcc/topmost

X11: improve handling of WS_EX_TOPMOST

Changed paths:
  M mcs/class/Managed.Windows.Forms/System.Windows.Forms/Hwnd.cs
  M mcs/class/Managed.Windows.Forms/System.Windows.Forms/XplatUIX11.cs

Modified: mcs/class/Managed.Windows.Forms/System.Windows.Forms/Hwnd.cs
===================================================================
@@ -76,6 +76,7 @@ internal class Hwnd : IDisposable {
 		internal bool		whacky_wm;
 		internal bool		fixed_size;
 		internal bool		zombie; /* X11 only flag.  true if the X windows have been destroyed but we haven't been Disposed */
+		internal bool		topmost; /* X11 only. */
 		internal Region		user_clip;
 		internal XEventQueue	queue;
 		internal WindowExStyles	initial_ex_style;
@@ -122,6 +123,7 @@ internal class Hwnd : IDisposable {
 			children = new ArrayList ();
 			resizing_or_moving = false;
 			whacky_wm = false;
+			topmost = false;
 		}
 
 		public void Dispose() {

Modified: mcs/class/Managed.Windows.Forms/System.Windows.Forms/XplatUIX11.cs
===================================================================
@@ -1619,11 +1619,23 @@ static Hwnd.Borders FrameExtents (IntPtr window)
 				if (hwnd.zombie)
 					return;
 
-				if ((windows & WindowType.Whole) != 0) {
-					XMapWindow(DisplayHandle, hwnd.whole_window);
-				}
-				if ((windows & WindowType.Client) != 0) {
-					XMapWindow(DisplayHandle, hwnd.client_window);
+				if (hwnd.topmost) {
+					// Most window managers will respect the _NET_WM_STATE property.
+					// If not, use XMapRaised to map the window at the top level as
+					// a last ditch effort.
+					if ((windows & WindowType.Whole) != 0) {
+						XMapRaised(DisplayHandle, hwnd.whole_window);
+					}
+					if ((windows & WindowType.Client) != 0) {
+						XMapRaised(DisplayHandle, hwnd.client_window);
+					}
+				} else {
+					if ((windows & WindowType.Whole) != 0) {
+						XMapWindow(DisplayHandle, hwnd.whole_window);
+					}
+					if ((windows & WindowType.Client) != 0) {
+						XMapWindow(DisplayHandle, hwnd.client_window);
+					}
 				}
 
 				hwnd.mapped = true;
@@ -2972,13 +2984,8 @@ internal override IntPtr CreateWindow (CreateParams cp)
 					XSelectInput(DisplayHandle, hwnd.client_window, new IntPtr ((int)(SelectInputMask | EventMask.StructureNotifyMask | Keyboard.KeyEventMask)));
 			}
 
-			if (ExStyleSet (cp.ExStyle, WindowExStyles.WS_EX_TOPMOST)) {
-				atoms = new int[2];
-				atoms[0] = _NET_WM_WINDOW_TYPE_NORMAL.ToInt32();
-				XChangeProperty(DisplayHandle, hwnd.whole_window, _NET_WM_WINDOW_TYPE, (IntPtr)Atom.XA_ATOM, 32, PropertyMode.Replace, atoms, 1);
-
-				XSetTransientForHint (DisplayHandle, hwnd.whole_window, RootWindow);
-			}
+			if (ExStyleSet (cp.ExStyle, WindowExStyles.WS_EX_TOPMOST))
+				SetTopmost(hwnd.whole_window, true);
 
 			SetWMStyles(hwnd, cp);
 			
@@ -5787,6 +5794,7 @@ internal override bool SetTopmost(IntPtr handle, bool enabled)
 		{
 
 			Hwnd hwnd = Hwnd.ObjectFromHandle(handle);
+			hwnd.topmost = enabled;
 
 			if (enabled) {
 				lock (XlibLock) {
@@ -6405,6 +6413,13 @@ internal static int XMapWindow(IntPtr display, IntPtr window)
 			DebugHelper.TraceWriteLine ("XMapWindow");
 			return _XMapWindow(display, window);
 		}
+		[DllImport ("libX11", EntryPoint="XMapRaised")]
+		internal extern static int _XMapRaised(IntPtr display, IntPtr window);
+		internal static int XMapRaised(IntPtr display, IntPtr window)
+		{
+			DebugHelper.TraceWriteLine ("XMapRaised");
+			return _XMapRaised(display, window);
+		}
 		[DllImport ("libX11", EntryPoint="XUnmapWindow")]
 		internal extern static int _XUnmapWindow(IntPtr display, IntPtr window);
 		internal static int XUnmapWindow(IntPtr display, IntPtr window)
@@ -7255,6 +7270,9 @@ internal static void XIfEvent (IntPtr display, ref XEvent xevent, Delegate event
 		[DllImport ("libX11", EntryPoint="XMapWindow")]
 		internal extern static int XMapWindow(IntPtr display, IntPtr window);
 		
+		[DllImport ("libX11", EntryPoint="XMapRaised")]
+		internal extern static int XMapRaised(IntPtr display, IntPtr window);
+		
 		[DllImport ("libX11", EntryPoint="XUnmapWindow")]
 		internal extern static int XUnmapWindow(IntPtr display, IntPtr window);
 		
_______________________________________________
Mono-patches maillist  -  [email protected]
http://lists.ximian.com/mailman/listinfo/mono-patches
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.