From: Alex Rønne Petersen Date: Mon, 21 Oct 2013 18:19:47 +0000 (-0700) Subject: Merge pull request #260 from pcc/topmost X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=commitdiff_plain;h=e946a6cdebde729e1c03ec374184254ab38da184;hp=b86af4848657c5fa6041d0eefa47ac004dc54442;p=mono.git Merge pull request #260 from pcc/topmost X11: improve handling of WS_EX_TOPMOST --- diff --git a/mcs/class/Managed.Windows.Forms/System.Windows.Forms/Hwnd.cs b/mcs/class/Managed.Windows.Forms/System.Windows.Forms/Hwnd.cs index 404c0e2156a..505a41a0449 100644 --- a/mcs/class/Managed.Windows.Forms/System.Windows.Forms/Hwnd.cs +++ b/mcs/class/Managed.Windows.Forms/System.Windows.Forms/Hwnd.cs @@ -76,6 +76,7 @@ namespace System.Windows.Forms { 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 @@ namespace System.Windows.Forms { children = new ArrayList (); resizing_or_moving = false; whacky_wm = false; + topmost = false; } public void Dispose() { diff --git a/mcs/class/Managed.Windows.Forms/System.Windows.Forms/XplatUIX11.cs b/mcs/class/Managed.Windows.Forms/System.Windows.Forms/XplatUIX11.cs index 9b6c13014ae..be296615725 100644 --- a/mcs/class/Managed.Windows.Forms/System.Windows.Forms/XplatUIX11.cs +++ b/mcs/class/Managed.Windows.Forms/System.Windows.Forms/XplatUIX11.cs @@ -1619,11 +1619,23 @@ namespace System.Windows.Forms { 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 @@ namespace System.Windows.Forms { 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 @@ namespace System.Windows.Forms { { Hwnd hwnd = Hwnd.ObjectFromHandle(handle); + hwnd.topmost = enabled; if (enabled) { lock (XlibLock) { @@ -6405,6 +6413,13 @@ namespace System.Windows.Forms { 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 @@ namespace System.Windows.Forms { [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);