Ok, I know am becoming a spammer ;-)
I dug in depth and found a fix for the MDI issue; MapWindow() has almost the
same inconsistent WM_SHOWWINDOW handling issue as UnmapWindow() has.
Though this fix exposed another issue that ApplicationContext could send
WM_QUIT inappropriately from ExitThreadCore(). When there is no application
loop, there is nothing to quit.
Though they are needed for XIM changes, the changes above are not about XIM.
The entire XIM patch is here: http://monoport.com/10928
(It includes this patch. Also note that this patch is dirty!)
When this patch and patch for bugs I wrote earlier are applied, I could
finally checkin this XIM change.
Atsushi Eno
Atsushi Eno wrote:
Hello,
After fixing couple of issues, I found a fix for this
WaitForHwndMessage()
issue. The situation is that (in some cases?) WM_SHOWWINDOW could be
processed
synchronously inside SendMessage() and when we reach
WaitForHwndMessage(),
the MSG is already consumed and hence never shows up.
The attached patch fixes this issue. I'm still not sure why this does not
happen when we don't create XIM context for each client window, but
the sample repro in my last mail[*1] gets fixed with this patch.
If it looks okay, I'll commit this small change. I'm still not going
to commit
my XIM changes, as there are still pending fixes on bugzilla[*2] and
there
seems another MDI issue that needs fix too.
Atsushi Eno
*1 http://monoport.com/9806
*2 #325033 and #387693
Atsushi Eno wrote:
Hi,
I'm posting it as I've been stuck with this issue for couple of days and
I still don't have a fix.
Now I'm trying to fix XIM stuff to show up IM engine UI. Currently only
scim works (I tried scim-anthy). Everything else (as far as I tried,
iiimx/atokx3 and kinput2) do not work.
It is (to my understanding) due to incorrect use of "client window"
of the
input context (XIC). I fixed this issue with the patch [*1] but
it caused (or exposed) some regressions [*2][*3].
My guess is that there are some issues around X event filtering (as
XplatUIX11.WaitForHwndMessage does not finish) but I don't know how it
could be fixed.
I'll continue working on this issue but any help would be appreciated.
*1 http://monoport.com/9842
*2 Timer or Form.Close() causes infinite loop http://monoport.com/9804
... and it is not always reproducible.
*3 Form.set_Visible() causes infinite loop http://monoport.com/9806
Atsushi Eno
_______________________________________________
Mono-winforms-list maillist - [email protected]
http://lists.ximian.com/mailman/listinfo/mono-winforms-list
------------------------------------------------------------------------
_______________________________________________
Mono-winforms-list maillist - [email protected]
http://lists.ximian.com/mailman/listinfo/mono-winforms-list
Index: System.Windows.Forms/Control.cs
===================================================================
--- System.Windows.Forms/Control.cs (revision 102695)
+++ System.Windows.Forms/Control.cs (working copy)
@@ -5725,6 +5725,7 @@
if (IsDisposed)
return;
+ Form frm = this as Form;
if (m.WParam.ToInt32() != 0) {
if (m.LParam.ToInt32 () == 0) {
CreateControl ();
@@ -5747,8 +5748,6 @@
} else {
if (parent != null && Focused) {
Control container;
- Form frm = this as Form;
-
// Need to start at parent, GetContainerControl might return ourselves if we're a container
container = (Control)parent.GetContainerControl();
if (container != null && (frm == null || !frm.IsMdiChild)) {
@@ -5757,10 +5756,12 @@
}
}
+ if (frm != null)
+ frm.waiting_showwindow = false;
+
// If the form is Max/Min, it got its OnVisibleChanged in SetVisibleCore
- Form f = this as Form;
- if (f != null) {
- if (!IsRecreating && (f.IsMdiChild || f.WindowState == FormWindowState.Normal)) /* XXX make sure this works for mdi forms */
+ if (frm != null) {
+ if (!IsRecreating && (frm.IsMdiChild || frm.WindowState == FormWindowState.Normal)) /* XXX make sure this works for mdi forms */
OnVisibleChanged(EventArgs.Empty);
} else if (is_toplevel)
OnVisibleChanged(EventArgs.Empty);
Index: System.Windows.Forms/XplatUIX11.cs
===================================================================
--- System.Windows.Forms/XplatUIX11.cs (revision 102695)
+++ System.Windows.Forms/XplatUIX11.cs (working copy)
@@ -1430,10 +1430,12 @@
private void MapWindow(Hwnd hwnd, WindowType windows) {
if (!hwnd.mapped) {
- if (Control.FromHandle(hwnd.Handle) is Form) {
- Form f = Control.FromHandle(hwnd.Handle) as Form;
- if (f.WindowState == FormWindowState.Normal)
+ Form f = Control.FromHandle(hwnd.Handle) as Form;
+ if (f != null) {
+ if (f.WindowState == FormWindowState.Normal) {
+ f.waiting_showwindow = true;
SendMessage(hwnd.Handle, Msg.WM_SHOWWINDOW, (IntPtr)1, IntPtr.Zero);
+ }
}
// it's possible that our Hwnd is no
@@ -1442,44 +1444,40 @@
if (hwnd.zombie)
return;
- bool need_to_wait = false;
-
if ((windows & WindowType.Whole) != 0) {
XMapWindow(DisplayHandle, hwnd.whole_window);
}
if ((windows & WindowType.Client) != 0) {
XMapWindow(DisplayHandle, hwnd.client_window);
-
- need_to_wait = true;
}
hwnd.mapped = true;
- if (need_to_wait && Control.FromHandle(hwnd.Handle) is Form)
+ if (f != null && f.waiting_showwindow)
WaitForHwndMessage (hwnd, Msg.WM_SHOWWINDOW);
}
}
private void UnmapWindow(Hwnd hwnd, WindowType windows) {
if (hwnd.mapped) {
+ Form f = null;
if (Control.FromHandle(hwnd.Handle) is Form) {
- Form f = Control.FromHandle(hwnd.Handle) as Form;
- if (f.WindowState == FormWindowState.Normal)
+ f = Control.FromHandle(hwnd.Handle) as Form;
+ if (f.WindowState == FormWindowState.Normal) {
+ f.waiting_showwindow = true;
SendMessage(hwnd.Handle, Msg.WM_SHOWWINDOW, IntPtr.Zero, IntPtr.Zero);
+ }
}
// it's possible that our Hwnd is no
// longer valid after making that
// SendMessage call, so check here.
+ // FIXME: it is likely wrong, as it has already sent WM_SHOWWINDOW
if (hwnd.zombie)
return;
- bool need_to_wait = false;
-
if ((windows & WindowType.Client) != 0) {
XUnmapWindow(DisplayHandle, hwnd.client_window);
-
- need_to_wait = true;
}
if ((windows & WindowType.Whole) != 0) {
XUnmapWindow(DisplayHandle, hwnd.whole_window);
@@ -1487,7 +1485,7 @@
hwnd.mapped = false;
- if (need_to_wait && Control.FromHandle(hwnd.Handle) is Form)
+ if (f != null && f.waiting_showwindow)
WaitForHwndMessage (hwnd, Msg.WM_SHOWWINDOW);
}
}
Index: System.Windows.Forms/Form.cs
===================================================================
--- System.Windows.Forms/Form.cs (revision 102695)
+++ System.Windows.Forms/Form.cs (working copy)
@@ -92,6 +92,7 @@
private bool shown_raised; // The shown event is only raised once
private bool is_clientsize_set;
internal bool suppress_closing_events;
+ internal bool waiting_showwindow; // for XplatUIX11
#if NET_2_0
private MenuStrip main_menu_strip;
Index: System.Windows.Forms/ApplicationContext.cs
===================================================================
--- System.Windows.Forms/ApplicationContext.cs (revision 102695)
+++ System.Windows.Forms/ApplicationContext.cs (working copy)
@@ -106,7 +106,8 @@
}
protected virtual void ExitThreadCore() {
- XplatUI.PostQuitMessage(0);
+ if (Application.MWFThread.Current.Context == this)
+ XplatUI.PostQuitMessage(0);
if (!thread_exit_raised && ThreadExit != null) {
thread_exit_raised = true;
ThreadExit(this, EventArgs.Empty);
_______________________________________________
Mono-winforms-list maillist - [email protected]
http://lists.ximian.com/mailman/listinfo/mono-winforms-list