Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Implement local grabs on macOS. |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | core-8-6-branch |
Files: | files | file ages | folders |
SHA3-256: |
1edd8b7a1638926304bbbfef3688863b |
User & Date: | culler 2019-01-08 23:01:32 |
References
2022-04-02
| ||
20:44 | • Ticket [dc4c5573] tk_popup entry index not working on unix status still Open with 4 other changes artifact: 583222ce user: fvogel | |
Context
2019-01-10
| ||
08:10 | Fix [9e31fd9449]: X11/X.h and Windows.h have conflicting symbols. *** POTENTIAL INCOMPATIBILITY *** on Windows only: gcc/clang/MSVC will generate new warnings in extensions when the "None" symbol is used incorrectly. Those warnings are all fixed in the core, that's what most of this commit is doing. check-in: c707c501 user: jan.nijtmans tags: core-8-6-branch | |
2019-01-09
| ||
14:28 | Fix bug [70e531918e]: geometry issues with menubuttons on macOS check-in: 06cc21c0 user: culler tags: bug-70e531918e | |
13:01 | Implement local grabs on macOS. check-in: 10f2f6f2 user: culler tags: trunk | |
2019-01-08
| ||
23:01 | Implement local grabs on macOS. check-in: 1edd8b7a user: culler tags: core-8-6-branch | |
22:53 | Update the demos to give a more complete explanation of local and global grabs. Closed-Leaf check-in: 97a0b2b5 user: culler tags: mac-local-grabs | |
2019-01-04
| ||
23:27 | Merge 8.5 check-in: dbb582dd user: jan.nijtmans tags: core-8-6-branch | |
Changes
Changes to doc/grab.n.
︙ | ︙ | |||
56 57 58 59 60 61 62 63 64 65 66 67 68 69 | if they are sent to any window in the grabbing application then they are redirected to the focus window. During a global grab Tk grabs the keyboard so that all keyboard events are always sent to the grabbing application. The \fBfocus\fR command is still used to determine which window in the application receives the keyboard events. The keyboard grab is released when the grab is released. .PP Grabs apply to particular displays. If an application has windows on multiple displays then it can establish a separate grab on each display. The grab on a particular display affects only the windows on that display. It is possible for different applications on a single display to have | > > > > > > > > > > | 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 | if they are sent to any window in the grabbing application then they are redirected to the focus window. During a global grab Tk grabs the keyboard so that all keyboard events are always sent to the grabbing application. The \fBfocus\fR command is still used to determine which window in the application receives the keyboard events. The keyboard grab is released when the grab is released. .PP On macOS a global grab affects all windows created by one Tk process. No window in that process other than the grab window can even be focused, hence no other window receives key or mouse events. A local grab on macOS affects all windows created by one Tcl interpreter. It is possible to focus any window belonging to the Tk process during a local grab but the grab window is the only window created by its interpreter which receives key or mouse events. Windows belonging to the same process but created by different interpreters continue to receive key and mouse events normally. .PP Grabs apply to particular displays. If an application has windows on multiple displays then it can establish a separate grab on each display. The grab on a particular display affects only the windows on that display. It is possible for different applications on a single display to have |
︙ | ︙ |
Changes to generic/tkGrab.c.
︙ | ︙ | |||
422 423 424 425 426 427 428 | if (dispPtr->eventualGrabWinPtr->mainPtr != winPtr->mainPtr) { goto alreadyGrabbed; } Tk_Ungrab((Tk_Window) dispPtr->eventualGrabWinPtr); } Tk_MakeWindowExist(tkwin); | < | < < < < | 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 | if (dispPtr->eventualGrabWinPtr->mainPtr != winPtr->mainPtr) { goto alreadyGrabbed; } Tk_Ungrab((Tk_Window) dispPtr->eventualGrabWinPtr); } Tk_MakeWindowExist(tkwin); if (!grabGlobal) { Window dummy1, dummy2; int dummy3, dummy4, dummy5, dummy6; unsigned int state; /* * Local grab. However, if any mouse buttons are down, turn it into a * global grab temporarily, until the last button goes up. This does |
︙ | ︙ |
Changes to library/demos/dialog1.tcl.
1 2 3 4 5 | # dialog1.tcl -- # # This demonstration script creates a dialog box with a local grab. after idle {.dialog1.msg configure -wraplength 4i} | > > > > > > > > | > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | # dialog1.tcl -- # # This demonstration script creates a dialog box with a local grab. interp create slave load {} Tk slave slave eval { wm title . slave wm geometry . +700+30 pack [text .t -width 30 -height 10] } after idle {.dialog1.msg configure -wraplength 4i} set i [tk_dialog .dialog1 "Dialog with local grab" {This is a modal dialog box. It uses Tk's "grab" command to create a "local grab" on the dialog box. The grab prevents any mouse or keyboard events from getting to any other windows in the application until you have answered the dialog by invoking one of the buttons below. However, you can still interact with other applications. For example, you should be able to edit text in the window named "slave" which was created by a slave interpreter.} \ info 0 OK Cancel {Show Code}] switch $i { 0 {puts "You pressed OK"} 1 {puts "You pressed Cancel"} 2 {showCode .dialog1} } if {[interp exists slave]} { interp delete slave } |
Changes to library/demos/dialog2.tcl.
1 2 3 4 5 6 7 8 9 10 | # dialog2.tcl -- # # This demonstration script creates a dialog box with a global grab. after idle { .dialog2.msg configure -wraplength 4i } after 100 { grab -global .dialog2 } | | > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | # dialog2.tcl -- # # This demonstration script creates a dialog box with a global grab. after idle { .dialog2.msg configure -wraplength 4i } after 100 { grab -global .dialog2 } set i [tk_dialog .dialog2 "Dialog with global grab" {This dialog box uses a global grab. If you are using an X11 window manager you will be prevented from interacting with anything on your display until you invoke one of the buttons below. This is almost always a bad idea; don't use global grabs with X11 unless you're truly desperate. On macOS systems you will not be able to interact with any window belonging to this process, but interaction with other macOS Applications will still be possible.}\ warning 0 OK Cancel {Show Code}] switch $i { 0 {puts "You pressed OK"} 1 {puts "You pressed Cancel"} 2 {showCode .dialog2} } |
Changes to macosx/tkMacOSXKeyEvent.c.
︙ | ︙ | |||
135 136 137 138 139 140 141 | state |= Mod3Mask; } if (modifiers & NSFunctionKeyMask) { state |= Mod4Mask; } /* | | > > | | > > | > > | | > | > > | 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 | state |= Mod3Mask; } if (modifiers & NSFunctionKeyMask) { state |= Mod4Mask; } /* * Events are only received for the front Window on the Macintosh. * So to build an XEvent we look up the Tk window associated to the * Front window. If a different window has a local grab we ignore * the event. */ TkWindow *winPtr = TkMacOSXGetTkWindow(w); Tk_Window tkwin = (Tk_Window) winPtr; if (tkwin) { TkWindow *grabWinPtr = winPtr->dispPtr->grabWinPtr; if (grabWinPtr && grabWinPtr != winPtr && !winPtr->dispPtr->grabFlags && /* this means the grab is local. */ grabWinPtr->mainPtr == winPtr->mainPtr) { return theEvent; } } else { tkwin = (Tk_Window) winPtr->dispPtr->focusPtr; } if (!tkwin) { TkMacOSXDbgMsg("tkwin == NULL"); return theEvent; /* Give up. No window for this event. */ } /* * If it's a function key, or we have modifiers other than Shift or Alt, * pass it straight to Tk. Otherwise we'll send for input processing. */ int code = (len == 0) ? 0 : [charactersIgnoringModifiers characterAtIndex: 0]; if (type != NSKeyDown || isFunctionKey(code) || (len > 0 && state & (ControlMask | Mod1Mask | Mod3Mask | Mod4Mask))) { XEvent xEvent; setupXEvent(&xEvent, w, state); |
︙ | ︙ |
Changes to macosx/tkMacOSXMouseEvent.c.
︙ | ︙ | |||
102 103 104 105 106 107 108 | global.y = tkMacOSXZeroScreenHeight - global.y; } else { /* We have no window. Use the screen???*/ local.y = tkMacOSXZeroScreenHeight - local.y; global = local; } } | | | | | > > > > > > > > > > > | | < | < | 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 | global.y = tkMacOSXZeroScreenHeight - global.y; } else { /* We have no window. Use the screen???*/ local.y = tkMacOSXZeroScreenHeight - local.y; global = local; } } TkWindow *winPtr = TkMacOSXGetTkWindow(eventWindow); Tk_Window tkwin = (Tk_Window) winPtr; if (tkwin) { TkWindow *grabWinPtr = winPtr->dispPtr->grabWinPtr; if (grabWinPtr && grabWinPtr != winPtr && !winPtr->dispPtr->grabFlags && /* this means the grab is local. */ grabWinPtr->mainPtr == winPtr->mainPtr) { return theEvent; } } else { tkwin = TkMacOSXGetCapture(); } if (!tkwin) { TkMacOSXDbgMsg("tkwin == NULL"); return theEvent; /* Give up. No window for this event. */ } else { winPtr = (TkWindow *)tkwin; } local.x -= winPtr->wmInfoPtr->xInParent; local.y -= winPtr->wmInfoPtr->yInParent; int win_x, win_y; tkwin = Tk_TopCoordsToWindow(tkwin, local.x, local.y, &win_x, &win_y); unsigned int state = 0; NSInteger button = [theEvent buttonNumber]; EventRef eventRef = (EventRef)[theEvent eventRef]; UInt32 buttons; OSStatus err = GetEventParameter(eventRef, kEventParamMouseChord, typeUInt32, NULL, sizeof(UInt32), NULL, &buttons); |
︙ | ︙ |