Tk Source Code

Artifact [f637dd05]
Login

Artifact f637dd0504e6475f9e69309e869e811c3fbde67e:

Attachment "full_screen_7.patch" to ticket [1032982f] added by mdejong 2004-10-31 03:56:46.
Index: doc/wm.n
===================================================================
RCS file: /cvsroot/tktoolkit/tk/doc/wm.n,v
retrieving revision 1.11.2.2
diff -u -r1.11.2.2 wm.n
--- doc/wm.n	28 Oct 2004 22:40:57 -0000	1.11.2.2
+++ doc/wm.n	30 Oct 2004 20:08:08 -0000
@@ -66,6 +66,9 @@
 a value from \fB0.0\fR (fully transparent) to \fB1.0\fR (opaque).  Values
 outside that range will be constrained.  This is supported on Windows
 2000/XP+.  Where not supported, the \fB\-alpha\fR value remains at
+\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.
 \fB1.0\fR.
 .PP
 On Macintosh, there are currently two attribute values:
Index: tests/winWm.test
===================================================================
RCS file: /cvsroot/tktoolkit/tk/tests/winWm.test,v
retrieving revision 1.9.2.3
diff -u -r1.9.2.3 winWm.test
--- tests/winWm.test	5 Oct 2004 22:27:27 -0000	1.9.2.3
+++ tests/winWm.test	30 Oct 2004 20:08:09 -0000
@@ -232,7 +232,7 @@
     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
@@ -243,7 +243,7 @@
     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
Index: tests/wm.test
===================================================================
RCS file: /cvsroot/tktoolkit/tk/tests/wm.test,v
retrieving revision 1.21.2.3
diff -u -r1.21.2.3 wm.test
--- tests/wm.test	29 Oct 2004 22:34:06 -0000	1.21.2.3
+++ tests/wm.test	30 Oct 2004 20:08:10 -0000
@@ -132,20 +132,312 @@
 
 test wm-attributes-1.2.1 {usage} {pcOnly} {
     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} {pcOnly} {
     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} {pcOnly} {
     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} {macOrUnix} {
     list [catch {wm attributes . _} err] $err
 } {1 {wrong # args: should be "wm attributes window"}}
 
+test wm-attributes-1.3.0 {default -fullscreen value} {
+    deleteWindows
+    toplevel .t
+    wm attributes .t -fullscreen
+} {0}
+
+test wm-attributes-1.3.1 {change -fullscreen before map} {
+    deleteWindows
+    toplevel .t
+    wm attributes .t -fullscreen 1
+    wm attributes .t -fullscreen
+} {1}
+
+test wm-attributes-1.3.2 {change -fullscreen before map} {
+    deleteWindows
+    toplevel .t
+    wm attributes .t -fullscreen 1
+    update
+    wm attributes .t -fullscreen
+} {1}
+
+test wm-attributes-1.3.3 {change -fullscreen after map} {
+    deleteWindows
+    toplevel .t
+    update
+    wm attributes .t -fullscreen 1
+    wm attributes .t -fullscreen
+} {1}
+
+test wm-attributes-1.3.4 {change -fullscreen after map} {
+    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} {
+    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} {
+    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} {
+    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} {
+    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} {
+    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} {
+    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} {
+    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} {
+    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} {
+    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} {
+    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} {
+    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} {
+    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} {
+    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} {
+    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} {
+    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} {
+    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
 
 test wm-client-1.1 {usage} {
     list [catch {wm client} err] $err
@@ -1682,9 +1974,10 @@
 # if the window was raised after a button click for example.
 # This sort of testing may not be possible.
 
-
 deleteWindows
 tcltest::cleanupTests
+catch {results}
+catch {focusin}
 return
 
 
Index: win/tkWinWm.c
===================================================================
RCS file: /cvsroot/tktoolkit/tk/win/tkWinWm.c,v
retrieving revision 1.54.2.16
diff -u -r1.54.2.16 tkWinWm.c
--- win/tkWinWm.c	29 Oct 2004 22:34:06 -0000	1.54.2.16
+++ win/tkWinWm.c	30 Oct 2004 20:08:16 -0000
@@ -230,6 +230,8 @@
 				 * 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 @@
  * 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 @@
 #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 @@
 #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)
 
@@ -2010,6 +2019,9 @@
 	    } 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;
@@ -2045,10 +2057,16 @@
 	/*
 	 * 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;
@@ -2414,6 +2432,73 @@
     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);
+	    }
+	}   
+    }
+}
 
 /*
  *--------------------------------------------------------------
@@ -2858,6 +2943,8 @@
     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:
@@ -2865,6 +2952,7 @@
 		"window"
 		" ?-alpha ?double??"
 		" ?-disabled ?bool??"
+		" ?-fullscreen ?bool??"
 		" ?-toolwindow ?bool??"
 		" ?-topmost ?bool??");
 	return TCL_ERROR;
@@ -2881,6 +2969,10 @@
 	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)));
@@ -2902,6 +2994,9 @@
 	} 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;
@@ -2964,7 +3059,16 @@
 			    != 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) {
@@ -2995,6 +3099,34 @@
 	    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;
 }
 
@@ -5430,7 +5562,7 @@
      */
 
     if (wmPtr->wrapper && (IsIconic(wmPtr->wrapper) ||
-	    IsZoomed(wmPtr->wrapper))) {
+	    IsZoomed(wmPtr->wrapper) || (wmPtr->flags & WM_FULLSCREEN))) {
 	return;
     }