summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorstanton <stanton>1998-08-05 18:22:44 (GMT)
committerstanton <stanton>1998-08-05 18:22:44 (GMT)
commitfd1e519f5ce2e0c9df64512e26bc82dababa2861 (patch)
tree8cbcffc607fabe923ccc65007b6ada504a6f90f1
parentdc55832efa2a9060428f2e81fefb4e21559e5e95 (diff)
downloadtk-fd1e519f5ce2e0c9df64512e26bc82dababa2861.zip
tk-fd1e519f5ce2e0c9df64512e26bc82dababa2861.tar.gz
tk-fd1e519f5ce2e0c9df64512e26bc82dababa2861.tar.bz2
Local grabs did not exclude menus or the caption bar
wm frame would crash if the window had not been mapped yet
-rw-r--r--win/tkWinWm.c97
1 files changed, 96 insertions, 1 deletions
diff --git a/win/tkWinWm.c b/win/tkWinWm.c
index 3a280f4..4e77d3e 100644
--- a/win/tkWinWm.c
+++ b/win/tkWinWm.c
@@ -17,6 +17,17 @@
#include "tkWinInt.h"
/*
+ * Event structure for synthetic activation events. These events are
+ * placed on the event queue whenever a toplevel gets a WM_MOUSEACTIVATE
+ * message.
+ */
+
+typedef struct ActivateEvent {
+ Tcl_Event ev;
+ TkWindow *winPtr;
+} ActivateEvent;
+
+/*
* A data structure of the following type holds information for
* each window manager protocol (such as WM_DELETE_WINDOW) for
* which a handler (i.e. a Tcl command) has been defined for a
@@ -211,7 +222,8 @@ typedef struct TkWmInfo {
#define WM_TRANSIENT_STYLE \
(WS_POPUP|WS_CAPTION|WS_SYSMENU|WS_CLIPSIBLINGS|CS_DBLCLKS)
-#define EX_TRANSIENT_STYLE (WS_EX_TOOLWINDOW | WS_EX_DLGMODALFRAME)
+#define EX_TRANSIENT_STYLE \
+ (WS_EX_TOOLWINDOW|WS_EX_DLGMODALFRAME)
/*
* This module keeps a list of all top-level windows.
@@ -282,6 +294,8 @@ static int firstWindow = 1;
* Forward declarations for procedures defined in this file:
*/
+static int ActivateWindow _ANSI_ARGS_((Tcl_Event *evPtr,
+ int flags));
static void ConfigureEvent _ANSI_ARGS_((TkWindow *winPtr,
XConfigureEvent *eventPtr));
static void ConfigureTopLevel _ANSI_ARGS_((WINDOWPOS *pos));
@@ -1361,6 +1375,9 @@ Tk_WmCmd(clientData, interp, argc, argv)
argv[0], " frame window\"", (char *) NULL);
return TCL_ERROR;
}
+ if (Tk_WindowId((Tk_Window) winPtr) == None) {
+ Tk_MakeWindowExist((Tk_Window) winPtr);
+ }
hwnd = wmPtr->wrapper;
if (hwnd == NULL) {
hwnd = Tk_GetHWND(Tk_WindowId((Tk_Window) winPtr));
@@ -3966,6 +3983,44 @@ WmProc(hwnd, message, wParam, lParam)
result = 0;
goto done;
+ case WM_NCHITTEST: {
+ winPtr = GetTopLevel(hwnd);
+ if (winPtr && (TkGrabState(winPtr) == TK_GRAB_EXCLUDED)) {
+ /*
+ * This window is outside the grab heirarchy, so don't let any
+ * of the normal non-client processing occur. Note that this
+ * implementation is not strictly correct because the grab
+ * might change between now and when the event would have been
+ * processed by Tk, but it's close enough.
+ */
+
+ result = HTCLIENT;
+ goto done;
+ }
+ break;
+ }
+
+ case WM_MOUSEACTIVATE: {
+ ActivateEvent *eventPtr;
+ winPtr = GetTopLevel((HWND) wParam);
+
+ /*
+ * Don't activate the window yet since there may be grabs
+ * that should take precedence. Instead we need to queue
+ * an event so we can check the grab state right before we
+ * handle the mouse event.
+ */
+
+ if (winPtr) {
+ eventPtr = (ActivateEvent *)ckalloc(sizeof(ActivateEvent));
+ eventPtr->ev.proc = ActivateWindow;
+ eventPtr->winPtr = winPtr;
+ Tcl_QueueEvent((Tcl_Event*)eventPtr, TCL_QUEUE_TAIL);
+ }
+ result = MA_NOACTIVATE;
+ goto done;
+ }
+
default:
break;
}
@@ -4120,3 +4175,43 @@ TkpGetWrapperWindow(
}
return winPtr;
}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ActivateWindow --
+ *
+ * This function is called when an ActivateEvent is processed.
+ *
+ * Results:
+ * Returns 1 to indicate that the event was handled, else 0.
+ *
+ * Side effects:
+ * May activate the toplevel window associated with the event.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+ActivateWindow(
+ Tcl_Event *evPtr, /* Pointer to ActivateEvent. */
+ int flags) /* Notifier event mask. */
+{
+ TkWindow *winPtr;
+
+ if (! (flags & TCL_WINDOW_EVENTS)) {
+ return 0;
+ }
+
+ winPtr = ((ActivateEvent *) evPtr)->winPtr;
+
+ /*
+ * Ensure that the window is not excluded by a grab.
+ */
+
+ if (winPtr && (TkGrabState(winPtr) != TK_GRAB_EXCLUDED)) {
+ SetFocus(Tk_GetHWND(winPtr->window));
+ }
+
+ return 1;
+}