Hey
While trying to fix #413898, I found that we are not activating the related
form when setting Form.Visible to true, as opposed to .net (we actually do
that in Application.RunLoop, however, which is used by both
Application.Run() and Form.ShowDialog()).
An additional problem is the fact that trying to activate the form when made
visible (Form.SetVisibleCore in this case) is not a guarantee of receiving
the WM_ACTIVATE message in time before the form gets closed (not a problem
in both Application.Run and Form.ShowDialog), specially because we have to
send a message to the window manager, then wait for a X message, then
internally process in our own winforms queue.
So after trying several approachs, I came up with the simple attached patch,
that basically adds a synchronized version of the XplatUI.Activate method,
which in X11 sends the appropriate message to the window manager and then
sits to wait till we have processed it. Even if simple, and could run all
the test suite, I'm not very sure, because a synchronized call sounds
dangerous, and because I thought that maybe somebody could know why we
hadn't something like this before ;-).
Thoughts?
Carlos.
Index: XplatUI.cs
===================================================================
--- XplatUI.cs (revisión: 129872)
+++ XplatUI.cs (copia de trabajo)
@@ -464,6 +464,11 @@
driver.Activate(handle);
}
+ internal static void ActivateSynchronously (IntPtr handle)
+ {
+ driver.ActivateSynchronously (handle);
+ }
+
internal static void AudibleAlert() {
#if DriverDebug
Console.WriteLine("AudibleAlert(): Called");
Index: XplatUIDriver.cs
===================================================================
--- XplatUIDriver.cs (revisión: 129872)
+++ XplatUIDriver.cs (copia de trabajo)
@@ -325,6 +325,7 @@
internal abstract void SetWindowPos(IntPtr handle, int x, int y, int width, int height);
internal abstract void GetWindowPos(IntPtr handle, bool is_toplevel, out int x, out int y, out int width, out int height, out int client_width, out int client_height);
internal abstract void Activate(IntPtr handle);
+ internal abstract void ActivateSynchronously (IntPtr handle);
internal abstract void EnableWindow(IntPtr handle, bool Enable);
internal abstract void SetModal(IntPtr handle, bool Modal);
internal abstract void Invalidate(IntPtr handle, Rectangle rc, bool clear);
Index: XplatUIX11.cs
===================================================================
--- XplatUIX11.cs (revisión: 129872)
+++ XplatUIX11.cs (copia de trabajo)
@@ -2522,6 +2522,15 @@
}
}
+ internal override void ActivateSynchronously (IntPtr handle) {
+ Activate (handle);
+
+ // Don't wait for any activation handling, since it's not done by x11 for popup windows
+ CreateParams cp = Control.FromHandle (handle).GetCreateParams ();
+ if (!StyleSet (cp.Style, WindowStyles.WS_POPUP))
+ WaitForHwndMessage (Hwnd.ObjectFromHandle (handle), Msg.WM_ACTIVATE, true);
+ }
+
internal override void AudibleAlert() {
XBell(DisplayHandle, 0);
return;
Index: XplatUIWin32.cs
===================================================================
--- XplatUIWin32.cs (revisión: 129872)
+++ XplatUIWin32.cs (copia de trabajo)
@@ -1899,6 +1899,10 @@
}
}
+ internal override void ActivateSynchronously(IntPtr handle) {
+ Activate (handle);
+ }
+
internal override void Invalidate(IntPtr handle, Rectangle rc, bool clear) {
RECT rect;
Index: Form.cs
===================================================================
--- Form.cs (revisión: 129872)
+++ Form.cs (copia de trabajo)
@@ -2501,6 +2501,10 @@
SendControlFocus (ActiveControl);
else
this.Focus ();
+
+ // Activate synchronously only if this form can *truly* be activated
+ if (!IsActive && Parent == null && !IsMdiContainer && Visible)
+ XplatUI.ActivateSynchronously (window.Handle);
}
}
Index: XplatUICarbon.cs
===================================================================
--- XplatUICarbon.cs (revisión: 129872)
+++ XplatUICarbon.cs (copia de trabajo)
@@ -789,6 +789,10 @@
ActiveWindow = handle;
}
+ internal override void ActivateSynchronously (IntPtr handle) {
+ Activate (handle);
+ }
+
internal override void AudibleAlert() {
throw new NotImplementedException();
}
_______________________________________________
Mono-winforms-list maillist - [email protected]
http://lists.ximian.com/mailman/listinfo/mono-winforms-list