// Send a fake "LeaveNotify" event to a popup window. private static void FakeLeave(InputOutputWidget window) { if (window != null) { XEvent xevent = new XEvent(); xevent.xany.type__ = (Xlib.Xint)(int)(EventType.LeaveNotify); window.DispatchEvent(ref xevent); } }
// Dispatch an event to this widget. internal override void DispatchEvent(ref XEvent xevent) { XKeySym keysym; PopupWindow popup; InputOutputWidget child = null; switch ((EventType)(xevent.xany.type__)) { case EventType.ButtonPress: { // A mouse button was pressed during the grab. lock (this) { if (lastButton != null) { // We currently have a button window, so // all mouse events should go to it. popup = lastButton; } else { // Determine which popup contains the mouse. // If nothing contains, then use the top. popup = Find(xevent.xbutton.x_root, xevent.xbutton.y_root, true); } lastButton = popup; } // Find the child window. child = FindChild(popup, xevent.xbutton.x_root, xevent.xbutton.y_root); ChangeEntered(popup, child); if (popup != null) { // Adjust the co-ordinates and re-dispatch. xevent.xbutton.x__ = (Xlib.Xint)(xevent.xbutton.x_root - popup.x); xevent.xbutton.y__ = (Xlib.Xint)(xevent.xbutton.y_root - popup.y); popup.DispatchEvent(ref xevent); // Re-dispatch to the child window if necessary. if (child != null) { xevent.xbutton.x__ -= child.x; xevent.xbutton.y__ -= child.y; child.DispatchEvent(ref xevent); } } } break; case EventType.ButtonRelease: { // A mouse button was released during the grab. lock (this) { popup = lastButton; if (popup != null) { // Reset "lastButton" if this is the last // button to be released. ModifierMask mask = ModifierMask.AllButtons; mask &= (ModifierMask) ~((int)ModifierMask.Button1Mask << ((int)(xevent.xbutton.button__) - 1)); if ((xevent.xbutton.state & mask) == 0) { lastButton = null; } } } // Find the child window. child = FindChild(popup, xevent.xbutton.x_root, xevent.xbutton.y_root); ChangeEntered(popup, child); if (popup != null) { // Adjust the co-ordinates and re-dispatch. xevent.xbutton.x__ = (Xlib.Xint)(xevent.xbutton.x_root - popup.x); xevent.xbutton.y__ = (Xlib.Xint)(xevent.xbutton.y_root - popup.y); popup.DispatchEvent(ref xevent); // Re-dispatch to the child window if necessary. if (child != null) { xevent.xbutton.x__ -= child.x; xevent.xbutton.y__ -= child.y; child.DispatchEvent(ref xevent); } } } break; case EventType.MotionNotify: { // The mouse pointer was moved during the grab. lock (this) { // If there is a last button window, then use // that, otherwise find the one under the mouse. popup = lastButton; if (popup == null) { popup = Find(xevent.xmotion.x_root, xevent.xmotion.y_root, false); } } // Find the child window. child = FindChild(popup, xevent.xbutton.x_root, xevent.xbutton.y_root); ChangeEntered(popup, child); if (popup != null) { // Adjust the co-ordinates and re-dispatch. xevent.xmotion.x__ = (Xlib.Xint)(xevent.xmotion.x_root - popup.x); xevent.xmotion.y__ = (Xlib.Xint)(xevent.xmotion.y_root - popup.y); popup.DispatchEvent(ref xevent); // Re-dispatch to the child window if necessary. if (child != null) { xevent.xbutton.x__ -= child.x; xevent.xbutton.y__ -= child.y; child.DispatchEvent(ref xevent); } } } break; case EventType.KeyPress: { // Convert the event into a symbol and a string. if (keyBuffer == IntPtr.Zero) { keyBuffer = Marshal.AllocHGlobal(32); } keysym = 0; int len = Xlib.XLookupString (ref xevent.xkey, keyBuffer, 32, ref keysym, IntPtr.Zero); String str; if (len > 0) { str = Marshal.PtrToStringAnsi(keyBuffer, len); } else { str = null; } // Dispatch the event to the top-most popup. lock (this) { if (list.Length > 0) { popup = list[list.Length - 1]; } else { popup = null; } } if (popup != null) { // Find the child window. child = FindFocusedChild(popup); if (child == null) { popup.DispatchKeyEvent ((KeyName)keysym, xevent.xkey.state, str); } else { child.DispatchKeyEvent ((KeyName)keysym, xevent.xkey.state, str); } } } break; case EventType.KeyRelease: { // Convert the event into a symbol and a string. if (keyBuffer == IntPtr.Zero) { keyBuffer = Marshal.AllocHGlobal(32); } keysym = 0; int len = Xlib.XLookupString (ref xevent.xkey, keyBuffer, 32, ref keysym, IntPtr.Zero); // Dispatch the event to the top-most popup. lock (this) { if (list.Length > 0) { popup = list[list.Length - 1]; } else { popup = null; } } if (popup != null) { // Find the child window. child = FindFocusedChild(popup); if (child == null) { popup.DispatchKeyReleaseEvent ((KeyName)keysym, xevent.xkey.state); } else { child.DispatchKeyReleaseEvent ((KeyName)keysym, xevent.xkey.state); } } } break; default: { // Everything else is handled normally. base.DispatchEvent(ref xevent); } break; } }
// Send a fake "LeaveNotify" event to a popup window. private static void FakeLeave(InputOutputWidget window) { if(window != null) { XEvent xevent = new XEvent(); xevent.xany.type__ = (Xlib.Xint)(int)(EventType.LeaveNotify); window.DispatchEvent(ref xevent); } }