diff options
author | culler <culler> | 2019-01-04 00:49:35 (GMT) |
---|---|---|
committer | culler <culler> | 2019-01-04 00:49:35 (GMT) |
commit | fd6508a2a0aa568a36f853f326794536601769f0 (patch) | |
tree | fbc638cb9281478d92aec05f4a34e93953413bc1 | |
parent | 9997531222f9a5ea6e8da18ca5eb0241f06c0c61 (diff) | |
parent | e1188642314803f517fa3b8cf093d7ef0d20fe3e (diff) | |
download | tk-fd6508a2a0aa568a36f853f326794536601769f0.zip tk-fd6508a2a0aa568a36f853f326794536601769f0.tar.gz tk-fd6508a2a0aa568a36f853f326794536601769f0.tar.bz2 |
Resolve bug [18a4ba19bd]. Make winfo containing behave consistently across
platforms and fix a bug with embedded toplevels.
-rw-r--r-- | doc/winfo.n | 3 | ||||
-rw-r--r-- | macosx/tkMacOSXSubwindows.c | 6 | ||||
-rw-r--r-- | macosx/tkMacOSXWm.c | 50 | ||||
-rw-r--r-- | tests/unixWm.test | 175 | ||||
-rw-r--r-- | tests/wm.test | 2 | ||||
-rw-r--r-- | unix/tkUnixWm.c | 67 |
6 files changed, 203 insertions, 100 deletions
diff --git a/doc/winfo.n b/doc/winfo.n index 5008448..a833e31 100644 --- a/doc/winfo.n +++ b/doc/winfo.n @@ -73,6 +73,9 @@ to the screen containing \fIwindow\fR; otherwise they refer to the screen of the application's main window. If no window in this application contains the point then an empty string is returned. +An empty string is also returned if the point lies in the title bar +or border of its highest containing toplevel in this application. +(Note that with some window managers the borders may be invisible.) In selecting the containing window, children are given higher priority than parents and among siblings the highest one in the stacking order is chosen. diff --git a/macosx/tkMacOSXSubwindows.c b/macosx/tkMacOSXSubwindows.c index 0f9214f..7bc807a 100644 --- a/macosx/tkMacOSXSubwindows.c +++ b/macosx/tkMacOSXSubwindows.c @@ -157,11 +157,15 @@ XMapWindow( * the app to activate too early can make the menu bar * unresponsive. */ + TkMacOSXApplyWindowAttributes(macWin->winPtr, win); + [win setExcludedFromWindowsMenu:NO]; [NSApp activateIgnoringOtherApps:NO]; + [[win contentView] setNeedsDisplay:YES]; if ( [win canBecomeKeyWindow] ) { [win makeKeyAndOrderFront:NSApp]; + } else { + [win orderFrontRegardless]; } - TkMacOSXApplyWindowAttributes(macWin->winPtr, win); } else { /* * Rebuild the container's clipping region and display diff --git a/macosx/tkMacOSXWm.c b/macosx/tkMacOSXWm.c index 5cf0820..eb826a6 100644 --- a/macosx/tkMacOSXWm.c +++ b/macosx/tkMacOSXWm.c @@ -152,13 +152,13 @@ static const struct { typedef enum { WMATT_ALPHA, WMATT_FULLSCREEN, WMATT_MODIFIED, WMATT_NOTIFY, WMATT_TITLEPATH, WMATT_TOPMOST, WMATT_TRANSPARENT, - _WMATT_LAST_ATTRIBUTE + WMATT_TYPE, _WMATT_LAST_ATTRIBUTE } WmAttribute; static const char *const WmAttributeNames[] = { "-alpha", "-fullscreen", "-modified", "-notify", "-titlepath", "-topmost", "-transparent", - NULL + "-type", NULL }; /* @@ -594,7 +594,8 @@ SetWindowSizeLimits( * * FrontWindowAtPoint -- * - * Find frontmost toplevel window at a given screen location. + * Find frontmost toplevel window at a given screen location which has the + * specified mainPtr. If the location is in the title bar, return NULL. * * Results: * TkWindow*. @@ -607,7 +608,8 @@ SetWindowSizeLimits( static TkWindow* FrontWindowAtPoint( - int x, int y) + int x, + int y) { NSPoint p = NSMakePoint(x, tkMacOSXZeroScreenHeight - y); NSArray *windows = [NSApp orderedWindows]; @@ -615,11 +617,28 @@ FrontWindowAtPoint( for (NSWindow *w in windows) { winPtr = TkMacOSXGetTkWindow(w); - if (winPtr && NSMouseInRect(p, [w frame], NO)) { - break; + if (winPtr) { + WmInfo *wmPtr = winPtr->wmInfoPtr; + NSRect windowFrame = [w frame]; + NSRect contentFrame = [w frame]; + contentFrame.size.height = [[w contentView] frame].size.height; + /* + * For consistency with other platforms, points in the + * title bar are not considered to be contained in the + * window. + */ + + if ((wmPtr->hints.initial_state == NormalState || + wmPtr->hints.initial_state == ZoomState)) { + if (NSMouseInRect(p, contentFrame, NO)) { + return winPtr; + } else if (NSMouseInRect(p, windowFrame, NO)) { + return NULL; + } + } } } - return winPtr; + return NULL; } /* @@ -814,10 +833,6 @@ TkWmMapWindow( */ XMapWindow(winPtr->display, winPtr->window); - - /*Add window to Window menu.*/ - NSWindow *win = TkMacOSXDrawableWindow(winPtr->window); - [win setExcludedFromWindowsMenu:NO]; } /* @@ -1301,7 +1316,7 @@ WmSetAttribute( #if !(MAC_OS_X_VERSION_MAX_ALLOWED < 1070) [macWindow toggleFullScreen:macWindow]; #else - TKLog(@"The fullscreen attribute is ignored on this system.."); + TKLog(@"The fullscreen attribute is ignored on this system."); #endif } break; @@ -1379,6 +1394,9 @@ WmSetAttribute( TK_PARENT_WINDOW); } break; + case WMATT_TYPE: + TKLog(@"The type attribute is ignored on macOS."); + break; case _WMATT_LAST_ATTRIBUTE: default: return TCL_ERROR; @@ -1429,6 +1447,9 @@ WmGetAttribute( case WMATT_TRANSPARENT: result = Tcl_NewBooleanObj(wmPtr->flags & WM_TRANSPARENT); break; + case WMATT_TYPE: + result = Tcl_NewStringObj("unsupported", -1); + break; case _WMATT_LAST_ATTRIBUTE: default: break; @@ -4386,7 +4407,7 @@ Tk_CoordsToWindow( * that contains point. */ int x, y; /* Coordinates in winPtr. */ int tmpx, tmpy, bd; - + /* * Step 1: find the top-level window that contains the desired point. */ @@ -4456,6 +4477,9 @@ Tk_CoordsToWindow( } winPtr = nextPtr; } + if (winPtr->mainPtr != ((TkWindow *) tkwin)->mainPtr) { + return NULL; + } return (Tk_Window) winPtr; } diff --git a/tests/unixWm.test b/tests/unixWm.test index a0224a1..12a2142 100644 --- a/tests/unixWm.test +++ b/tests/unixWm.test @@ -808,14 +808,15 @@ test unixWm-22.2 {Tk_WmCmd procedure, "iconbitmap" option} {unix testwrapper} { WM_HINTS] 0]]] lappend result [wm iconbitmap .t] $bit } {{} questhead 0x4 {} 0x0} -test unixWm-22.3.1 {Tk_WmCmd procedure, "iconbitmap" option for unix only} \ -{unix notAqua} { - list [catch {wm iconbitmap .t bad-bitmap} msg] $msg -} {1 {bitmap "bad-bitmap" not defined}} -test unixWm-22.3.2 {Tk_WmCmd procedure, "iconbitmap" option for Aqua only} \ -Aqua { +if {[tk windowingsystem] == "aqua"} { + set result_22_3 {0 {}} +} else { + set result_22_3 {1 {bitmap "bad-bitmap" not defined}} +} +test unixWm-22.3 {Tk_WmCmd procedure, "iconbitmap" option for unix only} \ +unix { list [catch {wm iconbitmap .t bad-bitmap} msg] $msg -} {1 {}} +} $result_22_3 test unixWm-23.1 {Tk_WmCmd procedure, "iconify" option} unix { list [catch {wm iconify .t 12} msg] $msg @@ -1218,13 +1219,14 @@ test unixWm-34.2 {Tk_WmCmd procedure, "sizefrom" option} {unix testwrapper} { test unixWm-34.3 {Tk_WmCmd procedure, "sizefrom" option} unix { list [catch {wm sizefrom .t none} msg] $msg } {1 {bad argument "none": must be program or user}} - -test unixWm-35.1.1 {Tk_WmCmd procedure, "state" option} {unix notAqua} { - list [catch {wm state .t 1} msg] $msg -} {1 {bad argument "1": must be normal, iconic, or withdrawn}} -test unixWm-35.1.2 {Tk_WmCmd procedure, "state" option} Aqua { +if {[tk windowingsystem] == "aqua"} { + set result_35_1 {1 {bad argument "1": must be normal, iconic, withdrawn, or zoomed}} +} else { + set result_35_1 {1 {bad argument "1": must be normal, iconic, or withdrawn}} +} +test unixWm-35.1 {Tk_WmCmd procedure, "state" option} {unix notAqua} { list [catch {wm state .t 1} msg] $msg -} {1 {bad argument "1": must be normal, iconic, withdrawn, or zoomed}} +} $result_35_1 test unixWm-35.2 {Tk_WmCmd procedure, "state" option} unix { list [catch {wm state .t iconic 1} msg] $msg } {1 {wrong # args: should be "wm state window ?state?"}} @@ -1777,88 +1779,103 @@ test unixWm-49.2 {Tk_GetRootCoords procedure, menubars} {unix testmenubar} { } {52 7 12 62} deleteWindows -wm iconify . -test unixWm-50.1 {Tk_CoordsToWindow procedure, finding a toplevel, x-coords} unix { - deleteWindows +wm withdraw . +if {[tk windowingsystem] == "aqua"} { + # Modern mac windows have no border. + set result_50_1 {{} {} .t .t .t2 {} .t2 .t .t} +} else { + # Windows are assumed to have a border (invisible in Gnome 3). + set result_50_1 {{} {} .t {} .t2 {} .t2 {} .t} +} +test unixWm-50.1 {Tk_CoordsToWindow procedure, finding a toplevel, x-coords, title bar} unix { + update toplevel .t -width 300 -height 400 -bg green - wm geom .t +40+0 + wm geom .t +100+100 tkwait visibility .t - toplevel .t2 -width 100 -height 80 -bg red - wm geom .t2 +140+200 + toplevel .t2 -width 100 -height 200 -bg red + wm geom .t2 +200+200 tkwait visibility .t2 raise .t2 + update set x [winfo rootx .t] set y [winfo rooty .t] - list [winfo containing [expr $x - 30] [expr $y + 250]] \ - [winfo containing [expr $x - 1] [expr $y + 250]] \ - [winfo containing $x [expr $y + 250]] \ - [winfo containing [expr $x + 99] [expr $y + 250]] \ - [winfo containing [expr $x + 100] [expr $y + 250]] \ - [winfo containing [expr $x + 199] [expr $y + 250]] \ - [winfo containing [expr $x + 200] [expr $y + 250]] \ - [winfo containing [expr $x + 220] [expr $y + 250]] -} {{} {} .t {} .t2 .t2 {} .t} + list [winfo containing [expr $x - 30] [expr $y + 250]] \ + [winfo containing [expr $x - 1] [expr $y + 250]] \ + [winfo containing $x [expr $y + 250]] \ + [winfo containing [expr $x + 99] [expr $y + 250]] \ + [winfo containing [expr $x + 100] [expr $y + 250]] \ + [winfo containing [expr $x + 150] [expr $y + 90]] \ + [winfo containing [expr $x + 199] [expr $y + 250]] \ + [winfo containing [expr $x + 200] [expr $y + 250]] \ + [winfo containing [expr $x + 220] [expr $y + 250]] \ +} $result_50_1 test unixWm-50.2 {Tk_CoordsToWindow procedure, finding a toplevel, y-coords and overrideredirect} unix { deleteWindows - toplevel .t -width 300 -height 400 -bg yellow - wm geom .t +0+50 + toplevel .t -width 400 -height 300 -bg yellow + wm geom .t +100+100 tkwait visibility .t - toplevel .t2 -width 100 -height 80 -bg blue + toplevel .t2 -width 200 -height 100 -bg blue wm overrideredirect .t2 1 - wm geom .t2 +100+200 + wm geom .t2 +200+200 tkwait visibility .t2 raise .t2 set x [winfo rootx .t] set y [winfo rooty .t] set y2 [winfo rooty .t2] - list [winfo containing [expr $x +150] 10] \ - [winfo containing [expr $x +150] [expr $y - 1]] \ - [winfo containing [expr $x +150] $y] \ - [winfo containing [expr $x +150] [expr $y2 - 1]] \ - [winfo containing [expr $x +150] $y2] \ - [winfo containing [expr $x +150] [expr $y2 + 79]] \ - [winfo containing [expr $x +150] [expr $y2 + 80]] \ - [winfo containing [expr $x +150] [expr $y + 450]] + list [winfo containing [expr $x +200] [expr $y - 30]] \ + [winfo containing [expr $x +200] [expr $y - 1]] \ + [winfo containing [expr $x +200] $y] \ + [winfo containing [expr $x +200] [expr $y2 - 1]] \ + [winfo containing [expr $x +200] $y2] \ + [winfo containing [expr $x +200] [expr $y2 + 99]] \ + [winfo containing [expr $x +200] [expr $y2 + 100]] \ + [winfo containing [expr $x +200] [expr $y + 450]] } {{} {} .t .t .t2 .t2 .t {}} test unixWm-50.3 { Tk_CoordsToWindow procedure, finding a toplevel with embedding -} -constraints tempNotWin -setup { +} tempNotWin { deleteWindows + catch {interp delete slave} + toplevel .t -width 300 -height 400 -bg blue - wm geom .t +0+50 - frame .t.f -container 1 + wm geom .t +100+100 + frame .t.f -container 1 -bg red place .t.f -x 150 -y 50 tkwait visibility .t.f - setupbg -} -body { - dobg " + update + interp create slave + load {} Tk slave + slave alias frameid winfo id .t.f + slave eval { wm withdraw . - toplevel .x -width 100 -height 80 -use [winfo id .t.f] -bg yellow - tkwait visibility .x" - set result [dobg { - set x [winfo rootx .x] - set y [winfo rooty .x] - list [winfo containing [expr $x - 1] [expr $y + 50]] \ - [winfo containing $x [expr $y +50]] - }] + toplevel .x -width 100 -height 80 -use [frameid] -bg yellow + tkwait visibility .x + update + set x [winfo rootx .x] + set y [winfo rooty .x] + } + set result [list [slave eval {winfo containing [expr $x - 1] [expr $y + 50]}] \ + [slave eval {winfo containing $x [expr $y + 50]}]] + interp delete slave set x [winfo rootx .t] set y [winfo rooty .t] lappend result [winfo containing [expr $x + 200] [expr $y + 49]] \ - [winfo containing [expr $x + 200] [expr $y +50]] -} -cleanup { - cleanupbg -} -result {{} .x .t .t.f} + [winfo containing [expr $x + 200] [expr $y +50]] + set result +} {{} .x .t .t.f} test unixWm-50.4 {Tk_CoordsToWindow procedure, window in other application} unix { destroy .t + catch {interp delete slave} toplevel .t -width 200 -height 200 -bg green - wm geometry .t +0+0 + wm geometry .t +100+100 tkwait visibility .t + update interp create slave load {} Tk slave - slave eval {wm geometry . 200x200+0+0; tkwait visibility .} - set result [list [winfo containing 100 100] \ - [slave eval {winfo containing 100 100}]] + slave eval {wm geometry . 200x200+100+100; tkwait visibility . ; update} + set result [list [winfo containing 200 200] \ + [slave eval {winfo containing 200 200}]] interp delete slave set result } {{} .} @@ -1876,13 +1893,13 @@ test unixWm-50.5 {Tk_CoordsToWindow procedure, handling menubars} {unix testmenu update set x [winfo rootx .t] set y [winfo rooty .t] - list [winfo containing $x [expr $y - 31]] \ - [winfo containing $x [expr $y - 30]] \ - [winfo containing [expr $x + 50] [expr $y - 19]] \ - [winfo containing [expr $x + 50] [expr $y - 18]] \ - [winfo containing [expr $x + 50] $y] \ - [winfo containing [expr $x + 11] [expr $y + 152]] \ - [winfo containing [expr $x + 12] [expr $y + 152]] + list [winfo containing $x [expr $y - 31]] \ + [winfo containing $x [expr $y - 30]] \ + [winfo containing [expr $x + 50] [expr $y - 19]] \ + [winfo containing [expr $x + 50] [expr $y - 18]] \ + [winfo containing [expr $x + 50] $y] \ + [winfo containing [expr $x + 11] [expr $y + 152]] \ + [winfo containing [expr $x + 12] [expr $y + 152]] } {{} .t.menu .t.menu .t.menu.f .t .t .t.f} test unixWm-50.6 {Tk_CoordsToWindow procedure, embedding within one app.} unix { deleteWindows @@ -1947,6 +1964,7 @@ test unixWm-50.9 {Tk_CoordsToWindow procedure, unmapped windows} unix { tkwait visibility .t2 set result [list [winfo containing 100 100]] wm iconify .t2 + animationDelay lappend result [winfo containing 100 100] } {.t2 .t} test unixWm-50.10 {Tk_CoordsToWindow procedure, unmapped windows} unix { @@ -2032,6 +2050,7 @@ test unixWm-51.6 {TkWmRestackToplevel procedure, window to be stacked isn't mapp test unixWm-51.7 {TkWmRestackToplevel procedure, other window isn't mapped} unix { foreach w {.t .t2 .t3} { destroy $w + update toplevel $w -width 200 -height 200 -bg green wm geometry $w +0+0 } @@ -2068,13 +2087,19 @@ test unixWm-51.8 {TkWmRestackToplevel procedure, overrideredirect windows} unix raise .t2 lappend result [winfo containing $x $y] } {.t2 .t .t2} +# The mac won't put an overrideredirect window above the root, +if {[tk windowingsystem] == "aqua"} { + wm withdraw . +} test unixWm-51.9 {TkWmRestackToplevel procedure, other window overrideredirect} unix { foreach w {.t .t2 .t3} { destroy $w + update toplevel $w -width 200 -height 200 -bg green wm overrideredirect $w 1 wm geometry $w +0+0 tkwait visibility $w + update } lower .t3 .t2 update @@ -2090,6 +2115,9 @@ test unixWm-51.9 {TkWmRestackToplevel procedure, other window overrideredirect} lower .t2 lappend result [winfo containing $x $y] } {.t2 .t3} +if {[tk windowingsystem] == "aqua"} { + wm deiconify . +} test unixWm-51.10 {TkWmRestackToplevel procedure, don't move window that's already in the right place} unix { makeToplevels raise .raise1 @@ -2465,11 +2493,18 @@ test unixWm-59.3 {exit processing} unix { # NOTE: since [wm attributes] is not guaranteed to have any effect, # the only thing we can really test here is the syntax. # +if {[tk windowingsystem] == "aqua"} { + set result_60_1 {-alpha 1.0 -fullscreen 0 -modified 0 -notify 0\ + -titlepath {} -topmost 0 -transparent 0\ + -type unsupported} +} else { + set result_60_1 {-alpha 1.0 -topmost 0 -zoomed 0 -fullscreen 0 -type {}} +} test unixWm-60.1 {wm attributes - test} -constraints unix -body { destroy .t toplevel .t wm attributes .t -} -result [list -alpha 1.0 -topmost 0 -zoomed 0 -fullscreen 0 -type {}] +} -result $result_60_1 test unixWm-60.2 {wm attributes - test} -constraints unix -body { destroy .t diff --git a/tests/wm.test b/tests/wm.test index f56eaa7..7b81985 100644 --- a/tests/wm.test +++ b/tests/wm.test @@ -140,7 +140,7 @@ test wm-attributes-1.2.4 {usage} -constraints {unix notAqua} -returnCodes error } -result {bad attribute "_": must be -alpha, -topmost, -zoomed, -fullscreen, or -type} test wm-attributes-1.2.5 {usage} -constraints aqua -returnCodes error -body { wm attributes . _ -} -result {bad attribute "_": must be -alpha, -fullscreen, -modified, -notify, -titlepath, -topmost, or -transparent} +} -result {bad attribute "_": must be -alpha, -fullscreen, -modified, -notify, -titlepath, -topmost, -transparent, or -type} ### wm client ### diff --git a/unix/tkUnixWm.c b/unix/tkUnixWm.c index 19ac86c..8944ecc 100644 --- a/unix/tkUnixWm.c +++ b/unix/tkUnixWm.c @@ -5785,6 +5785,18 @@ Tk_GetRootCoords( *---------------------------------------------------------------------- */ +static int PointInWindow( + int x, + int y, + WmInfo *wmPtr) +{ + XWindowChanges changes = wmPtr->winPtr->changes; + return (x >= changes.x && + x < changes.x + changes.width && + y >= changes.y - wmPtr->menuHeight && + y < changes.y + changes.height); +} + Tk_Window Tk_CoordsToWindow( int rootX, int rootY, /* Coordinates of point in root window. If a @@ -5855,13 +5867,38 @@ Tk_CoordsToWindow( } for (wmPtr = (WmInfo *) dispPtr->firstWmPtr; wmPtr != NULL; wmPtr = wmPtr->nextPtr) { - if (wmPtr->reparent == child) { - goto gotToplevel; + if (wmPtr->winPtr->mainPtr == NULL) { + continue; + } + if (child == wmPtr->reparent) { + if (PointInWindow(x, y, wmPtr)) { + goto gotToplevel; + } else { + + /* + * Return NULL if the point is in the title bar or border. + */ + + return NULL; + } } if (wmPtr->wrapperPtr != NULL) { if (child == wmPtr->wrapperPtr->window) { goto gotToplevel; - } + } else if (wmPtr->winPtr->flags & TK_EMBEDDED && + TkpGetOtherWindow(wmPtr->winPtr) == NULL) { + + /* + * This toplevel is embedded in a window belonging to + * a different application. + */ + + int rx, ry; + Tk_GetRootCoords((Tk_Window) wmPtr->winPtr, &rx, &ry); + childX -= rx; + childY -= ry; + goto gotToplevel; + } } else if (child == wmPtr->winPtr->window) { goto gotToplevel; } @@ -5883,9 +5920,6 @@ Tk_CoordsToWindow( handler = NULL; } winPtr = wmPtr->winPtr; - if (winPtr->mainPtr != ((TkWindow *) tkwin)->mainPtr) { - return NULL; - } /* * Step 3: at this point winPtr and wmPtr refer to the toplevel that @@ -5942,27 +5976,30 @@ Tk_CoordsToWindow( if (nextPtr == NULL) { break; } - winPtr = nextPtr; - x -= winPtr->changes.x; - y -= winPtr->changes.y; - if ((winPtr->flags & TK_CONTAINER) - && (winPtr->flags & TK_BOTH_HALVES)) { + x -= nextPtr->changes.x; + y -= nextPtr->changes.y; + if ((nextPtr->flags & TK_CONTAINER) + && (nextPtr->flags & TK_BOTH_HALVES)) { /* * The window containing the point is a container, and the * embedded application is in this same process. Switch over to * the toplevel for the embedded application and start processing * that toplevel from scratch. */ - - winPtr = TkpGetOtherWindow(winPtr); + winPtr = TkpGetOtherWindow(nextPtr); if (winPtr == NULL) { - return NULL; + return (Tk_Window) nextPtr; } wmPtr = winPtr->wmInfoPtr; childX = x; childY = y; goto gotToplevel; - } + } else { + winPtr = nextPtr; + } + } + if (winPtr->mainPtr != ((TkWindow *) tkwin)->mainPtr) { + return NULL; } return (Tk_Window) winPtr; } |