diff options
-rw-r--r-- | ChangeLog | 12 | ||||
-rw-r--r-- | doc/wm.n | 6 | ||||
-rw-r--r-- | tests/winWm.test | 6 | ||||
-rw-r--r-- | tests/wm.test | 303 | ||||
-rw-r--r-- | win/tkWinWm.c | 142 |
5 files changed, 456 insertions, 13 deletions
@@ -1,3 +1,15 @@ +2005-02-16 Mo DeJong <mdejong@users.sourceforge.net> + + * doc/wm.n: Add documentation for -fullscreen attribute. + * tests/winWm.test: Add -fullscreen to wm attribute + usage message. + * tests/wm.test: Add -fullscreen to wm attribute + usage message. Add -fullscreen attribute test cases + for Windows. + * win/tkWinWm.c (WmInfo, UpdateWrapper, TkpWmSetFullScreen, + WmAttributesCmd, UpdateGeometryInfo): + Implement TIP 223 [wm attributes -fullscreen]. + 2005-02-14 Vince Darley <vincentdarley@users.sourceforge.net> * generic/tkText.c: @@ -5,7 +5,7 @@ '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. '\" -'\" RCS: @(#) $Id: wm.n,v 1.21 2004/11/11 01:24:31 das Exp $ +'\" RCS: @(#) $Id: wm.n,v 1.22 2005/02/17 00:06:08 mdejong Exp $ '\" .so man.macros .TH wm n 8.5 Tk "Tk Built-In Commands" @@ -69,6 +69,10 @@ outside that range will be constrained. This is supported on Windows 2000/XP+. Where not supported, the \fB\-alpha\fR value remains at \fB1.0\fR. .VE 8.5 +\fB\-fullscreen\fR attribute will place the window in a mode that +takes up the entire screen, has no borders, and covers the Start +menu and taskbar. +.VE 8.5 .PP On Mac OS X, \fB\-modified\fR gets or sets the modification state of the window (determines whether the window close widget contains the modification diff --git a/tests/winWm.test b/tests/winWm.test index f1449e4..95b71cb 100644 --- a/tests/winWm.test +++ b/tests/winWm.test @@ -9,7 +9,7 @@ # Copyright (c) 1998-1999 by Scriptics Corporation. # All rights reserved. # -# RCS: @(#) $Id: winWm.test,v 1.15 2004/12/04 00:04:43 dkf Exp $ +# RCS: @(#) $Id: winWm.test,v 1.16 2005/02/17 00:06:08 mdejong Exp $ package require tcltest 2.1 eval tcltest::configure $argv @@ -229,7 +229,7 @@ test winWm-6.1 {wm attributes} win { destroy .t toplevel .t wm attributes .t -} {-alpha 1.0 -disabled 0 -toolwindow 0 -topmost 0} +} {-alpha 1.0 -disabled 0 -fullscreen 0 -toolwindow 0 -topmost 0} test winWm-6.2 {wm attributes} win { destroy .t toplevel .t @@ -240,7 +240,7 @@ test winWm-6.3 {wm attributes} win { destroy .t toplevel .t list [catch {wm attributes .t -foo} msg] $msg -} {1 {wrong # args: should be "wm attributes window ?-alpha ?double?? ?-disabled ?bool?? ?-toolwindow ?bool?? ?-topmost ?bool??"}} +} {1 {wrong # args: should be "wm attributes window ?-alpha ?double?? ?-disabled ?bool?? ?-fullscreen ?bool?? ?-toolwindow ?bool?? ?-topmost ?bool??"}} test winWm-6.4 {wm attributes -alpha} win { # Expect this to return all 1.0 {} on pre-2K/XP diff --git a/tests/wm.test b/tests/wm.test index a214581..3b86f86 100644 --- a/tests/wm.test +++ b/tests/wm.test @@ -7,7 +7,7 @@ # Copyright (c) 1998-1999 by Scriptics Corporation. # All rights reserved. # -# RCS: @(#) $Id: wm.test,v 1.33 2005/02/15 03:22:10 chengyemao Exp $ +# RCS: @(#) $Id: wm.test,v 1.34 2005/02/17 00:06:08 mdejong Exp $ # This file tests window manager interactions that work across # platforms. Window manager tests that only work on a specific @@ -116,13 +116,13 @@ test wm-attributes-1.1 {usage} { } {1 {wrong # args: should be "wm option window ?arg ...?"}} test wm-attributes-1.2.1 {usage} win { list [catch {wm attributes . _} err] $err -} {1 {wrong # args: should be "wm attributes window ?-alpha ?double?? ?-disabled ?bool?? ?-toolwindow ?bool?? ?-topmost ?bool??"}} +} {1 {wrong # args: should be "wm attributes window ?-alpha ?double?? ?-disabled ?bool?? ?-fullscreen ?bool?? ?-toolwindow ?bool?? ?-topmost ?bool??"}} test wm-attributes-1.2.2 {usage} win { list [catch {wm attributes . -alpha 1.0 -disabled} err] $err -} {1 {wrong # args: should be "wm attributes window ?-alpha ?double?? ?-disabled ?bool?? ?-toolwindow ?bool?? ?-topmost ?bool??"}} +} {1 {wrong # args: should be "wm attributes window ?-alpha ?double?? ?-disabled ?bool?? ?-fullscreen ?bool?? ?-toolwindow ?bool?? ?-topmost ?bool??"}} test wm-attributes-1.2.3 {usage} win { list [catch {wm attributes . -to} err] $err -} {1 {wrong # args: should be "wm attributes window ?-alpha ?double?? ?-disabled ?bool?? ?-toolwindow ?bool?? ?-topmost ?bool??"}} +} {1 {wrong # args: should be "wm attributes window ?-alpha ?double?? ?-disabled ?bool?? ?-fullscreen ?bool?? ?-toolwindow ?bool?? ?-topmost ?bool??"}} test wm-attributes-1.2.4 {usage} unix { list [catch {wm attributes . _} err] $err } {1 {wrong # args: should be "wm attributes window"}} @@ -146,6 +146,299 @@ test wm-client-2.1 {setting and reading values} { } [list {} Miffo {}] +test wm-attributes-1.3.0 {default -fullscreen value} {win} { + deleteWindows + toplevel .t + wm attributes .t -fullscreen +} {0} + +test wm-attributes-1.3.1 {change -fullscreen before map} {win} { + deleteWindows + toplevel .t + wm attributes .t -fullscreen 1 + wm attributes .t -fullscreen +} {1} + +test wm-attributes-1.3.2 {change -fullscreen before map} {win} { + deleteWindows + toplevel .t + wm attributes .t -fullscreen 1 + update + wm attributes .t -fullscreen +} {1} + +test wm-attributes-1.3.3 {change -fullscreen after map} {win} { + deleteWindows + toplevel .t + update + wm attributes .t -fullscreen 1 + wm attributes .t -fullscreen +} {1} + +test wm-attributes-1.3.4 {change -fullscreen after map} {win} { + deleteWindows + toplevel .t + update + set booleans [list] + lappend booleans [wm attributes .t -fullscreen] + wm attributes .t -fullscreen 1 + lappend booleans [wm attributes .t -fullscreen] + # Query above should not clear fullscreen state + lappend booleans [wm attributes .t -fullscreen] + wm attributes .t -fullscreen 0 + lappend booleans [wm attributes .t -fullscreen] + set booleans +} {0 1 1 0} + +test wm-attributes-1.3.5 {change -fullscreen after map} {win} { + deleteWindows + toplevel .t + set normal_geom "301x302+101+102" + set fullscreen_geom "[winfo screenwidth .t]x[winfo screenheight .t]+0+0" + wm geom .t $normal_geom + update + set results [list] + lappend results [string equal [wm geom .t] $normal_geom] + wm attributes .t -fullscreen 1 + lappend results [string equal [wm geom .t] $fullscreen_geom] + wm attributes .t -fullscreen 0 + lappend results [string equal [wm geom .t] $normal_geom] + set results +} {1 1 1} + +test wm-attributes-1.3.6 {state change does not change -fullscreen} {win} { + deleteWindows + toplevel .t + update + wm attributes .t -fullscreen 1 + wm withdraw .t + wm deiconify .t + wm attributes .t -fullscreen +} {1} + +test wm-attributes-1.3.7 {state change does not change -fullscreen} {win} { + deleteWindows + toplevel .t + update + wm attributes .t -fullscreen 1 + wm iconify .t + wm deiconify .t + wm attributes .t -fullscreen +} {1} + +test wm-attributes-1.3.8 {override-redirect not compatible with fullscreen attribute} {win} { + deleteWindows + toplevel .t + update + wm overrideredirect .t 1 + list [catch {wm attributes .t -fullscreen 1} err] $err +} {1 {can't set fullscreen attribute for ".t": override-redirect flag is set}} + +test wm-attributes-1.3.9 {max height too small} {win} { + deleteWindows + toplevel .t + update + wm maxsize .t 5000 450 + list [catch {wm attributes .t -fullscreen 1} err] $err +} {1 {can't set fullscreen attribute for ".t": max width/height is too small}} + +test wm-attributes-1.3.10 {max height too small} {win} { + deleteWindows + toplevel .t + update + wm maxsize .t 450 5000 + list [catch {wm attributes .t -fullscreen 1} err] $err +} {1 {can't set fullscreen attribute for ".t": max width/height is too small}} + +test wm-attributes-1.3.11 {another attribute, then -fullscreen} {win} { + deleteWindows + toplevel .t + update + wm attributes .t -alpha 1.0 -fullscreen 1 + wm attributes .t -fullscreen +} 1 + +test wm-attributes-1.3.12 {another attribute, then -fullscreen, then another} {win} { + deleteWindows + toplevel .t + update + wm attributes .t -toolwindow 0 -fullscreen 1 -topmost 0 + wm attributes .t -fullscreen +} 1 + +test wm-attributes-1.4.0 {setting/unsetting fullscreen does not change the focus} {win} { + deleteWindows + focus -force . + toplevel .t + lower .t + update + set results [list] + lappend results [focus] + + wm attributes .t -fullscreen 1 + after 200 "set done 1" ; vwait done + lappend results [focus] + + wm attributes .t -fullscreen 0 + after 200 "set done 1" ; vwait done + lappend results [focus] + + set results +} {. . .} + +test wm-attributes-1.4.1 {setting fullscreen does not generate FocusIn on wrapper create} {win} { + deleteWindows + catch {unset focusin} + focus -force . + toplevel .t + pack [entry .t.e] + lower .t + bind .t <FocusIn> {lappend focusin %W} + after 200 "set done 1" ; vwait done + + lappend focusin 1 + focus -force .t.e + after 200 "set done 1" ; vwait done + + lappend focusin 2 + wm attributes .t -fullscreen 1 + after 200 "set done 1" ; vwait done + + lappend focusin 3 + wm attributes .t -fullscreen 0 + after 200 "set done 1" ; vwait done + + lappend focusin final [focus] + + bind . <FocusIn> {} + bind .t <FocusIn> {} + set focusin +} {1 .t .t.e 2 3 final .t.e} + +test wm-attributes-1.5.0 {fullscreen stackorder} {win} { + deleteWindows + toplevel .t + set results [list] + lappend results [wm stackorder .] + after 200 "set done 1" ; vwait done + lappend results [wm stackorder .] + + # Default stacking is on top of other windows + # on the display. Setting the fullscreen attribute + # does not change this. + wm attributes .t -fullscreen 1 + after 200 "set done 1" ; vwait done + lappend results [wm stackorder .] + + set results +} {. {. .t} {. .t}} + +test wm-attributes-1.5.1 {fullscreen stackorder} {win} { + deleteWindows + toplevel .t + lower .t + after 200 "set done 1" ; vwait done + set results [list] + lappend results [wm stackorder .] + + # If stacking order is explicitly set, then + # setting the fullscreen attribute should + # not change it. + wm attributes .t -fullscreen 1 + after 200 "set done 1" ; vwait done + lappend results [wm stackorder .] + + set results +} {{.t .} {.t .}} + +test wm-attributes-1.5.2 {fullscreen stackorder} {win} { + deleteWindows + toplevel .t + # lower forces the window to be mapped, it would not be otherwise + lower .t + set results [list] + lappend results [wm stackorder .] + + # If stacking order is explicitly set + # for an unmapped window, then setting + # the fullscreen attribute should + # not change it. + wm attributes .t -fullscreen 1 + after 200 "set done 1" ; vwait done + lappend results [wm stackorder .] + + set results +} {{.t .} {.t .}} + +test wm-attributes-1.5.3 {fullscreen stackorder} {win} { + deleteWindows + toplevel .t + after 200 "set done 1" ; vwait done + set results [list] + lappend results [wm stackorder .] + + wm attributes .t -fullscreen 1 + after 200 "set done 1" ; vwait done + lappend results [wm stackorder .] + + # Unsetting the fullscreen attribute + # should not change the stackorder. + wm attributes .t -fullscreen 0 + after 200 "set done 1" ; vwait done + lappend results [wm stackorder .] + + set results +} {{. .t} {. .t} {. .t}} + +test wm-attributes-1.5.4 {fullscreen stackorder} {win} { + deleteWindows + toplevel .t + lower .t + after 200 "set done 1" ; vwait done + set results [list] + lappend results [wm stackorder .] + + wm attributes .t -fullscreen 1 + after 200 "set done 1" ; vwait done + lappend results [wm stackorder .] + + # Unsetting the fullscreen attribute + # should not change the stackorder. + wm attributes .t -fullscreen 0 + after 200 "set done 1" ; vwait done + lappend results [wm stackorder .] + + set results +} {{.t .} {.t .} {.t .}} + +test wm-attributes-1.5.5 {fullscreen stackorder} {win} { + deleteWindows + toplevel .a + toplevel .b + toplevel .c + raise .a + raise .b + raise .c + after 200 "set done 1" ; vwait done + set results [list] + lappend results [wm stackorder .] + + wm attributes .b -fullscreen 1 + after 200 "set done 1" ; vwait done + lappend results [wm stackorder .] + + # Unsetting the fullscreen attribute + # should not change the stackorder. + wm attributes .b -fullscreen 0 + after 200 "set done 1" ; vwait done + lappend results [wm stackorder .] + + set results +} {{. .a .b .c} {. .a .b .c} {. .a .b .c}} + +deleteWindows +stdWindow + ### wm colormapwindows ### test wm-colormapwindows-1.1 {usage} { list [catch {wm colormapwindows} err] $err @@ -1741,5 +2034,7 @@ test wm-deletion-epoch-1.1 {Deletion epoch on multiple displays} -constraints al deleteWindows cleanupTests +catch {unset results} +catch {unset focusin} return diff --git a/win/tkWinWm.c b/win/tkWinWm.c index df0478b..88042c1 100644 --- a/win/tkWinWm.c +++ b/win/tkWinWm.c @@ -12,7 +12,7 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkWinWm.c,v 1.96 2005/02/11 20:36:28 hobbs Exp $ + * RCS: @(#) $Id: tkWinWm.c,v 1.97 2005/02/17 00:06:09 mdejong Exp $ */ #include "tkWinInt.h" @@ -230,6 +230,8 @@ typedef struct TkWmInfo { * pixels for the current style/exStyle. This * includes the border on both sides of the * window. */ + int configX, configY; /* x,y position of toplevel when window is + * switched into fullscreen state, */ int configWidth, configHeight; /* Dimensions passed to last request that we * issued to change geometry of window. Used @@ -307,6 +309,9 @@ typedef struct TkWmInfo { * WM_WITHDRAWN - non-zero means that this window has explicitly * been withdrawn. If it's a transient, it should * not mirror state changes in the master. + * WM_FULLSCREEN - non-zero means that this window has been placed + * in the full screen mode. It should be mapped at + * 0,0 and be the width and height of the screen. */ #define WM_NEVER_MAPPED (1<<0) @@ -322,6 +327,7 @@ typedef struct TkWmInfo { #define WM_WIDTH_NOT_RESIZABLE (1<<10) #define WM_HEIGHT_NOT_RESIZABLE (1<<11) #define WM_WITHDRAWN (1<<12) +#define WM_FULLSCREEN (1<<13) /* * Window styles for various types of toplevel windows. @@ -330,6 +336,9 @@ typedef struct TkWmInfo { #define WM_OVERRIDE_STYLE (WS_CLIPCHILDREN|WS_CLIPSIBLINGS|CS_DBLCLKS) #define EX_OVERRIDE_STYLE (WS_EX_TOOLWINDOW) +#define WM_FULLSCREEN_STYLE (WS_POPUP|WM_OVERRIDE_STYLE) +#define EX_FULLSCREEN_STYLE (WS_EX_APPWINDOW) + #define WM_TOPLEVEL_STYLE (WS_OVERLAPPEDWINDOW|WS_CLIPCHILDREN|CS_DBLCLKS) #define EX_TOPLEVEL_STYLE (0) @@ -2020,6 +2029,9 @@ UpdateWrapper(winPtr) } else { wmPtr->style |= WS_POPUP; } + } else if (wmPtr->flags & WM_FULLSCREEN) { + wmPtr->style = WM_FULLSCREEN_STYLE; + wmPtr->exStyle = EX_FULLSCREEN_STYLE; } else if (wmPtr->masterPtr) { wmPtr->style = WM_TRANSIENT_STYLE; wmPtr->exStyle = EX_TRANSIENT_STYLE; @@ -2055,10 +2067,16 @@ UpdateWrapper(winPtr) /* * Set the initial position from the user or program specified * location. If nothing has been specified, then let the system - * pick a location. + * pick a location. In full screen mode the x,y origin is 0,0 + * and the window width and height match that of the screen. */ - if (!(wmPtr->sizeHintsFlags & (USPosition | PPosition)) + if (wmPtr->flags & WM_FULLSCREEN) { + x = 0; + y = 0; + width = WidthOfScreen(Tk_Screen(winPtr)); + height = HeightOfScreen(Tk_Screen(winPtr)); + } else if (!(wmPtr->sizeHintsFlags & (USPosition | PPosition)) && (wmPtr->flags & WM_NEVER_MAPPED)) { x = CW_USEDEFAULT; y = CW_USEDEFAULT; @@ -2436,6 +2454,73 @@ TkpWmSetState(winPtr, state) ShowWindow(wmPtr->wrapper, cmd); wmPtr->flags &= ~WM_SYNC_PENDING; } + + +/* + *---------------------------------------------------------------------- + * + * TkpWmSetFullScreen -- + * + * Sets the fullscreen state for a toplevel window. + * + * Results: + * The WM_FULLSCREEN flag is updated. + * + * Side effects: + * May create a new wrapper window and raise it. + * + *---------------------------------------------------------------------- + */ + +static +void +TkpWmSetFullScreen(winPtr, full_screen_state) + TkWindow *winPtr; /* Toplevel window to operate on. */ + int full_screen_state; /* True if window should be full screen */ +{ + int changed = 0; + int full_screen = False; + WmInfo *wmPtr = winPtr->wmInfoPtr; + TkWindow *focusWinPtr; + + if (full_screen_state) { + if (! (wmPtr->flags & WM_FULLSCREEN)) { + full_screen = True; + changed = 1; + } + } else { + if (wmPtr->flags & WM_FULLSCREEN) { + full_screen = False; + changed = 1; + } + } + + if (changed) { + if (full_screen) { + wmPtr->flags |= WM_FULLSCREEN; + wmPtr->configX = wmPtr->x; + wmPtr->configY = wmPtr->y; + } else { + wmPtr->flags &= ~WM_FULLSCREEN; + wmPtr->x = wmPtr->configX; + wmPtr->y = wmPtr->configY; + } + + /* If the window has been mapped, then we need to + * update the native wrapper window, and reset + * the focus to the widget that had it before. + */ + + if (!(wmPtr->flags & (WM_NEVER_MAPPED) + && !(winPtr->flags & TK_EMBEDDED))) { + UpdateWrapper(winPtr); + + if (focusWinPtr = TkGetFocusWin(winPtr)) { + TkSetFocusWin(focusWinPtr, 1); + } + } + } +} /* *---------------------------------------------------------------------- @@ -2906,6 +2991,8 @@ WmAttributesCmd(tkwin, winPtr, interp, objc, objv) LONG style, exStyle, styleBit, *stylePtr; char *string; int i, boolean, length; + int config_fullscreen = 0; + int fullscreen_attr_changed = 0, fullscreen_attr = 0; if ((objc < 3) || ((objc > 5) && ((objc%2) == 0))) { configArgs: @@ -2913,6 +3000,7 @@ WmAttributesCmd(tkwin, winPtr, interp, objc, objv) "window" " ?-alpha ?double??" " ?-disabled ?bool??" + " ?-fullscreen ?bool??" " ?-toolwindow ?bool??" " ?-topmost ?bool??"); return TCL_ERROR; @@ -2929,6 +3017,10 @@ WmAttributesCmd(tkwin, winPtr, interp, objc, objv) Tcl_ListObjAppendElement(NULL, objPtr, Tcl_NewBooleanObj((style & WS_DISABLED))); Tcl_ListObjAppendElement(NULL, objPtr, + Tcl_NewStringObj("-fullscreen", -1)); + Tcl_ListObjAppendElement(NULL, objPtr, + Tcl_NewBooleanObj((wmPtr->flags & WM_FULLSCREEN))); + Tcl_ListObjAppendElement(NULL, objPtr, Tcl_NewStringObj("-toolwindow", -1)); Tcl_ListObjAppendElement(NULL, objPtr, Tcl_NewBooleanObj((exStyle & WS_EX_TOOLWINDOW))); @@ -2950,6 +3042,9 @@ WmAttributesCmd(tkwin, winPtr, interp, objc, objv) } else if (strncmp(string, "-alpha", length) == 0) { stylePtr = &exStyle; styleBit = WS_EX_LAYERED; + } else if (strncmp(string, "-fullscreen", length) == 0) { + config_fullscreen = 1; + styleBit = 0; } else if ((length > 3) && (strncmp(string, "-toolwindow", length) == 0)) { stylePtr = &exStyle; @@ -3012,7 +3107,16 @@ WmAttributesCmd(tkwin, winPtr, interp, objc, objv) != TCL_OK)) { return TCL_ERROR; } - if (objc == 4) { + if (config_fullscreen) { + if (objc == 4) { + Tcl_SetBooleanObj(Tcl_GetObjResult(interp), + (wmPtr->flags & WM_FULLSCREEN)); + } else { + fullscreen_attr_changed = 1; + fullscreen_attr = boolean; + } + config_fullscreen = 0; + } else if (objc == 4) { Tcl_SetIntObj(Tcl_GetObjResult(interp), ((*stylePtr & styleBit) != 0)); } else if (boolean) { @@ -3043,6 +3147,34 @@ WmAttributesCmd(tkwin, winPtr, interp, objc, objv) UpdateWrapper(winPtr); } } + if (fullscreen_attr_changed) { + if (fullscreen_attr) { + if (Tk_Attributes((Tk_Window) winPtr)->override_redirect) { + Tcl_AppendResult(interp, "can't set fullscreen attribute for \"", + winPtr->pathName, + "\": override-redirect flag is set", + (char *) NULL); + return TCL_ERROR; + } + /* Check max width and height if set by the user, + * don't worry about the default values since they + * will likely be smaller than screen width/height. + */ + if (((wmPtr->maxWidth > 0) && + (WidthOfScreen(Tk_Screen(winPtr)) > wmPtr->maxWidth)) || + ((wmPtr->maxHeight > 0) && + (HeightOfScreen(Tk_Screen(winPtr)) > wmPtr->maxHeight))) { + Tcl_AppendResult(interp, "can't set fullscreen attribute for \"", + winPtr->pathName, + "\": max width/height is too small", + (char *) NULL); + return TCL_ERROR; + } + } + + TkpWmSetFullScreen(winPtr, fullscreen_attr); + } + return TCL_OK; } @@ -5508,7 +5640,7 @@ UpdateGeometryInfo(clientData) */ if (wmPtr->wrapper && (IsIconic(wmPtr->wrapper) || - IsZoomed(wmPtr->wrapper))) { + IsZoomed(wmPtr->wrapper) || (wmPtr->flags & WM_FULLSCREEN))) { return; } |