From eab645efcaf1952d13741e71ca0568212af825b5 Mon Sep 17 00:00:00 2001 From: das Date: Wed, 12 Dec 2007 23:44:21 +0000 Subject: * macosx/tkMacOSXWm.c (ApplyMasterOverrideChanges): Revert 2007-10-26 change to window class of transient toplevels that are not also overrideredirect. [Bug 1845899] * macosx/tkMacOSXWm.c (ApplyMasterOverrideChanges): Implement more * macosx/tkMacOSXMouseEvent.c (BringWindowForward): X11-like transient * macosx/tkMacOSXSubwindows.c (XDestroyWindow): behaviour by adding transient windows to a window group owned by the master window, this ensures transients always remain in front of and are collapsed with the master; bring master to front when selecting transient windows; restore default window group of transients if master destroyed. [Bug 1845899] --- ChangeLog | 14 ++++++ changes | 4 +- macosx/tkMacOSXMouseEvent.c | 25 +++++++++- macosx/tkMacOSXSubwindows.c | 37 ++++++++++++++- macosx/tkMacOSXWm.c | 109 +++++++++++++++++++++++++++++++------------- 5 files changed, 154 insertions(+), 35 deletions(-) diff --git a/ChangeLog b/ChangeLog index 1f5e2e0..1b5b1a2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +2007-12-12 Daniel Steffen + + * macosx/tkMacOSXWm.c (ApplyMasterOverrideChanges): Revert 2007-10-26 + change to window class of transient toplevels that are not also + overrideredirect. [Bug 1845899] + + * macosx/tkMacOSXWm.c (ApplyMasterOverrideChanges): Implement more + * macosx/tkMacOSXMouseEvent.c (BringWindowForward): X11-like transient + * macosx/tkMacOSXSubwindows.c (XDestroyWindow): behaviour by adding + transient windows to a window group owned by the master window, this + ensures transients always remain in front of and are collapsed with the + master; bring master to front when selecting transient windows; restore + default window group of transients if master destroyed. [Bug 1845899] + 2007-12-12 Joe English * doc/ttk_intro.n, doc/ttk_style.n, doc/ttk_widget.n: diff --git a/changes b/changes index 74405c8..d147ac6 100644 --- a/changes +++ b/changes @@ -2,7 +2,7 @@ This file summarizes all changes made to Tk since version 1.0 was released on March 13, 1991. Changes that aren't backward compatible are marked specially. -RCS: @(#) $Id: changes,v 1.117 2007/12/12 15:49:13 dgp Exp $ +RCS: @(#) $Id: changes,v 1.118 2007/12/12 23:44:21 das Exp $ 3/16/91 (bug fix) Modified tkWindow.c to remove Tk's Tcl commands from the interpreter when the main window is deleted (otherwise there will @@ -6454,6 +6454,8 @@ steffen, kupries) 2007-12-11 (bug fix)[1602537] crash in [$text replace] (goth,porter,fellows) +2007-12-12 (bug fix)[1845899] Aqua: [wm transient] (steffen) + Several documentation and release notes improvements --- Released 8.5.0, December 14, 2007 --- See ChangeLog for details --- diff --git a/macosx/tkMacOSXMouseEvent.c b/macosx/tkMacOSXMouseEvent.c index e8396b6..507fc31 100644 --- a/macosx/tkMacOSXMouseEvent.c +++ b/macosx/tkMacOSXMouseEvent.c @@ -54,7 +54,7 @@ * software in accordance with the terms specified in this * license. * - * RCS: @(#) $Id: tkMacOSXMouseEvent.c,v 1.32 2007/07/09 08:31:54 das Exp $ + * RCS: @(#) $Id: tkMacOSXMouseEvent.c,v 1.33 2007/12/12 23:44:22 das Exp $ */ #include "tkMacOSXPrivate.h" @@ -555,6 +555,29 @@ BringWindowForward( ChkErr(GetWindowModality, frontWindow, &frontWindowModality, NULL); } if (frontWindowModality != kWindowModalityAppModal) { + Window window = TkMacOSXGetXWindow(wRef); + + if (window != None) { + TkDisplay *dispPtr = TkGetDisplayList(); + TkWindow * winPtr = (TkWindow *)Tk_IdToWindow(dispPtr->display, + window); + + if (winPtr && winPtr->wmInfoPtr && + winPtr->wmInfoPtr->master != None) { + TkWindow *masterWinPtr = (TkWindow *)Tk_IdToWindow( + dispPtr->display, winPtr->wmInfoPtr->master); + + if (masterWinPtr && masterWinPtr->window != None && + TkMacOSXHostToplevelExists(masterWinPtr)) { + WindowRef masterMacWin = + TkMacOSXDrawableWindow(masterWinPtr->window); + + if (masterMacWin) { + BringToFront(masterMacWin); + } + } + } + } SelectWindow(wRef); } else { frontWindowOnly = 0; diff --git a/macosx/tkMacOSXSubwindows.c b/macosx/tkMacOSXSubwindows.c index dc21a3d..8a18765 100644 --- a/macosx/tkMacOSXSubwindows.c +++ b/macosx/tkMacOSXSubwindows.c @@ -10,7 +10,7 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkMacOSXSubwindows.c,v 1.25 2007/11/08 14:24:47 das Exp $ + * RCS: @(#) $Id: tkMacOSXSubwindows.c,v 1.26 2007/12/12 23:44:22 das Exp $ */ #include "tkMacOSXPrivate.h" @@ -109,7 +109,42 @@ XDestroyWindow( if (winRef) { TkMacOSXWindowList *listPtr, *prevPtr; + WindowGroupRef group; + + if (GetWindowProperty(winRef, 'Tk ', 'TsGp', sizeof(group), + NULL, &group) == noErr) { + TkDisplay *dispPtr = TkGetDisplayList(); + ItemCount i = CountWindowGroupContents(group, + kWindowGroupContentsReturnWindows); + + while (i > 0) { + WindowRef macWin; + + ChkErr(GetIndexedWindow, group, i--, 0, &macWin); + if (macWin) { + WindowGroupRef newGroup = NULL; + Window window = TkMacOSXGetXWindow(macWin); + + if (window != None) { + TkWindow * winPtr = (TkWindow *)Tk_IdToWindow( + dispPtr->display, window); + + if (winPtr && winPtr->wmInfoPtr) { + newGroup = GetWindowGroupOfClass( + winPtr->wmInfoPtr->macClass); + } + } + if (!newGroup) { + newGroup = GetWindowGroupOfClass( + kDocumentWindowClass); + } + ChkErr(SetWindowGroup, macWin, newGroup); + } + } + ChkErr(SetWindowGroupOwner, group, NULL); + ChkErr(ReleaseWindowGroup, group); + } TkMacOSXUnregisterMacWindow(winRef); DisposeWindow(winRef); diff --git a/macosx/tkMacOSXWm.c b/macosx/tkMacOSXWm.c index d4f6502..8f728e1 100644 --- a/macosx/tkMacOSXWm.c +++ b/macosx/tkMacOSXWm.c @@ -13,7 +13,7 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkMacOSXWm.c,v 1.61 2007/11/09 06:23:29 das Exp $ + * RCS: @(#) $Id: tkMacOSXWm.c,v 1.62 2007/12/12 23:44:21 das Exp $ */ #include "tkMacOSXPrivate.h" @@ -170,6 +170,7 @@ static void ApplyWindowClassAttributeChanges(TkWindow *winPtr, WindowRef macWindow, WindowClass oldClass, WindowAttributes oldAttributes, int create); static void ApplyMasterOverrideChanges(TkWindow *winPtr, WindowRef macWindow); +static WindowGroupRef WmGetWindowGroup(TkWindow *winPtr); static void GetMinSize(TkWindow *winPtr, int *minWidthPtr, int *minHeightPtr); static void GetMaxSize(TkWindow *winPtr, int *maxWidthPtr, int *maxHeightPtr); static void RemapWindows(TkWindow *winPtr, MacDrawable *parentWin); @@ -852,11 +853,10 @@ static int WmSetAttribute( if (boolean) { wmPtr->flags |= WM_TOPMOST; - group = GetWindowGroupOfClass(kUtilityWindowClass); } else { wmPtr->flags &= ~WM_TOPMOST; - group = GetWindowGroupOfClass(wmPtr->macClass); } + group = WmGetWindowGroup(winPtr); if (group && group != GetWindowGroup(macWindow)) { ChkErr(SetWindowGroup, macWindow, group); } @@ -6040,55 +6040,100 @@ ApplyMasterOverrideChanges( WmInfo *wmPtr = winPtr->wmInfoPtr; WindowClass oldClass = wmPtr->macClass; WindowAttributes oldAttributes = wmPtr->attributes; - const int wasOverrideredirect = (oldClass == kSimpleWindowClass && - oldAttributes == kWindowNoActivatesAttribute); - const int wasTransient = (oldClass == kPlainWindowClass && - oldAttributes == kWindowNoAttributes); - const int wasDefault = (oldClass == kDocumentWindowClass); /* * FIX: We need an UpdateWrapper equivalent to make this 100% correct */ + if (winPtr->atts.override_redirect) { - if (wasDefault || (wmPtr->master != None && wasTransient)) { + if (oldClass == kDocumentWindowClass) { wmPtr->macClass = kSimpleWindowClass; wmPtr->attributes = kWindowNoAttributes; } wmPtr->attributes |= kWindowNoActivatesAttribute; } else { - if (wmPtr->master != None) { - if (wasDefault || wasOverrideredirect) { - wmPtr->macClass = kPlainWindowClass; - wmPtr->attributes = kWindowNoAttributes; - } - } else { - if (wasTransient || wasOverrideredirect) { - wmPtr->macClass = kDocumentWindowClass; - wmPtr->attributes = kWindowStandardDocumentAttributes - | kWindowLiveResizeAttribute; - } + if (oldClass == kSimpleWindowClass && + oldAttributes == kWindowNoActivatesAttribute) { + wmPtr->macClass = kDocumentWindowClass; + wmPtr->attributes = kWindowStandardDocumentAttributes + | kWindowLiveResizeAttribute; } wmPtr->attributes &= ~kWindowNoActivatesAttribute; } - if (!macWindow) { - if (winPtr->window == None) { - return; - } - if (!TkMacOSXHostToplevelExists(winPtr)) { - return; - } + if (!macWindow && winPtr->window != None && + TkMacOSXHostToplevelExists(winPtr)) { macWindow = TkMacOSXDrawableWindow(winPtr->window); } if (macWindow) { - Tcl_Obj *val; + WindowGroupRef group; ApplyWindowClassAttributeChanges(winPtr, macWindow, oldClass, oldAttributes, 0); - val = Tcl_NewBooleanObj(winPtr->atts.override_redirect && - wmPtr->master != None); - WmSetAttribute(winPtr, macWindow, NULL, WMATT_TOPMOST, val); - Tcl_DecrRefCount(val); + + if (winPtr->atts.override_redirect && wmPtr->master != None) { + wmPtr->flags |= WM_TOPMOST; + } else { + wmPtr->flags &= ~WM_TOPMOST; + } + group = WmGetWindowGroup(winPtr); + if (group && group != GetWindowGroup(macWindow)) { + ChkErr(SetWindowGroup, macWindow, group); + } + } +} + +/* + *---------------------------------------------------------------------- + * + * WmGetWindowGroup -- + * + * Gets the window group a toplevel should be placed in. + * + * Results: + * A WindowGroupRef. + * + * Side effects: + * A transient window group for the master (if any) may be created. + * + *---------------------------------------------------------------------- + */ + +static WindowGroupRef +WmGetWindowGroup( + TkWindow *winPtr) +{ + WmInfo *wmPtr = winPtr->wmInfoPtr; + WindowGroupRef group = NULL; + + if (wmPtr->flags & WM_TOPMOST) { + group = GetWindowGroupOfClass(kUtilityWindowClass); + } else if (wmPtr->master != None) { + TkDisplay *dispPtr = TkGetDisplayList(); + TkWindow *masterWinPtr = (TkWindow *)Tk_IdToWindow(dispPtr->display, + wmPtr->master); + + if (masterWinPtr && masterWinPtr->window != None && + TkMacOSXHostToplevelExists(masterWinPtr)) { + WindowRef masterMacWin = + TkMacOSXDrawableWindow(masterWinPtr->window); + + if (masterMacWin && GetWindowProperty(masterMacWin, 'Tk ', 'TsGp', + sizeof(group), NULL, &group) != noErr) { + ChkErr(CreateWindowGroup, 0, &group); + if (group) { + ChkErr(SetWindowGroupParent, group, + GetWindowGroup(masterMacWin)); + ChkErr(SetWindowGroupOwner, group, masterMacWin); + ChkErr(SetWindowProperty, masterMacWin, 'Tk ', 'TsGp', + sizeof(group), &group); + } + } + } + } + if (!group) { + group = GetWindowGroupOfClass(wmPtr->macClass); } + return group; } /* -- cgit v0.12