Attachment "wmstyle.diff" to
ticket [553926ff]
added by
ericm
2002-05-09 05:31:16.
*** tkWinWm.c.bak Wed Sep 27 12:03:30 2000
--- tkWinWm.c Mon Oct 9 15:55:28 2000
***************
*** 165,170 ****
--- 165,171 ----
* property, or NULL. */
int flags; /* Miscellaneous flags, defined below. */
int numTransients; /* number of transients on this window */
+ int styleFlags; /* Flags for style information */
struct TkWmInfo *nextPtr; /* Next in list of all top-level windows. */
} WmInfo;
***************
*** 227,232 ****
--- 228,250 ----
#define EX_TRANSIENT_STYLE (WS_EX_DLGMODALFRAME)
/*
+ * Window styles for WinXX specific styles
+ */
+ #define WM_STYLE_CAPTION (1<<0)
+ #define WM_STYLE_DIALOG (1<<1)
+ #define WM_STYLE_MAXIMIZE (1<<2)
+ #define WM_STYLE_MINIMIZE (1<<3)
+ #define WM_STYLE_STAYONTOP (1<<4)
+ #define WM_STYLE_SYSMENU (1<<5)
+ #define WM_STYLE_TASKBAR (1<<6)
+ #define WM_STYLE_TRANSPARENT (1<<7)
+
+ #define WM_STYLE_INITIAL (WM_STYLE_CAPTION | WM_STYLE_MAXIMIZE | \
+ WM_STYLE_MINIMIZE | WM_STYLE_SYSMENU | \
+ WM_STYLE_TASKBAR)
+
+
+ /*
* The following structure is the official type record for geometry
* management of top-level windows.
*/
***************
*** 623,628 ****
--- 641,647 ----
wmPtr->cmdArgv = NULL;
wmPtr->clientMachine = NULL;
wmPtr->flags = WM_NEVER_MAPPED;
+ wmPtr->styleFlags = WM_STYLE_INITIAL;
wmPtr->nextPtr = winPtr->dispPtr->firstWmPtr;
winPtr->dispPtr->firstWmPtr = wmPtr;
***************
*** 675,680 ****
--- 694,701 ----
int *childStateInfo = NULL;
ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
+ int styleChanged = 0, exStyleChanged = 0;
+ HWND insertAfter = HWND_TOP;
parentHWND = NULL;
child = TkWinGetHWND(winPtr->window);
***************
*** 817,822 ****
--- 838,946 ----
SendMessage(wmPtr->wrapper, TK_ATTACHWINDOW, (WPARAM) child, 0);
/*
+ * Now, after the window has been created but before it has been
+ * mapped, apply any additional style flags. We need to do this
+ * before mapping for the taskbar style, so we just do them all
+ * here.
+ */
+ if (wmPtr->styleFlags != WM_STYLE_INITIAL) {
+ long style, exStyle;
+
+ style = GetWindowLong(wmPtr->wrapper, GWL_STYLE);
+ exStyle = GetWindowLong(wmPtr->wrapper, GWL_EXSTYLE);
+
+ if ((WM_STYLE_INITIAL & WM_STYLE_CAPTION) ^
+ (wmPtr->styleFlags & WM_STYLE_CAPTION)) {
+ styleChanged = 1;
+ if (wmPtr->styleFlags & WM_STYLE_CAPTION) {
+ style |= WS_CAPTION;
+ } else {
+ style &= ~WS_CAPTION;
+ }
+ }
+
+ if ((WM_STYLE_INITIAL & WM_STYLE_DIALOG) ^
+ (wmPtr->styleFlags & WM_STYLE_DIALOG)) {
+ exStyleChanged = 1;
+ if (wmPtr->styleFlags & WM_STYLE_DIALOG) {
+ exStyle |= WS_EX_DLGMODALFRAME;
+ } else {
+ exStyle &= ~WS_EX_DLGMODALFRAME;
+ }
+ }
+
+ if ((WM_STYLE_INITIAL & WM_STYLE_MAXIMIZE) ^
+ (wmPtr->styleFlags & WM_STYLE_MAXIMIZE)) {
+ styleChanged = 1;
+ if (wmPtr->styleFlags & WM_STYLE_MAXIMIZE) {
+ style |= WS_MAXIMIZEBOX;
+ } else {
+ style &= ~WS_MAXIMIZEBOX;
+ }
+ }
+
+ if ((WM_STYLE_INITIAL & WM_STYLE_MINIMIZE) ^
+ (wmPtr->styleFlags & WM_STYLE_MINIMIZE)) {
+ styleChanged = 1;
+ if (wmPtr->styleFlags & WM_STYLE_MINIMIZE) {
+ style |= WS_MINIMIZEBOX;
+ } else {
+ style &= ~WS_MINIMIZEBOX;
+ }
+ }
+
+ if ((WM_STYLE_INITIAL & WM_STYLE_STAYONTOP) ^
+ (wmPtr->styleFlags & WM_STYLE_STAYONTOP)) {
+ exStyleChanged = 1;
+ if (wmPtr->styleFlags & WM_STYLE_STAYONTOP) {
+ exStyle |= WS_EX_TOPMOST;
+ insertAfter = HWND_TOPMOST;
+ } else {
+ exStyle &= ~WS_EX_TOPMOST;
+ insertAfter = HWND_NOTOPMOST;
+ }
+ }
+
+ if ((WM_STYLE_INITIAL & WM_STYLE_SYSMENU) ^
+ (wmPtr->styleFlags & WM_STYLE_SYSMENU)) {
+ styleChanged = 1;
+ if (wmPtr->styleFlags & WM_STYLE_SYSMENU) {
+ style |= WS_SYSMENU;
+ } else {
+ style &= ~WS_SYSMENU;
+ }
+ }
+
+ if ((WM_STYLE_INITIAL & WM_STYLE_TASKBAR) ^
+ (wmPtr->styleFlags & WM_STYLE_TASKBAR)) {
+ exStyleChanged = 1;
+ if (wmPtr->styleFlags & WM_STYLE_TASKBAR) {
+ exStyle &= ~WS_EX_TOOLWINDOW;
+ } else {
+ exStyle |= WS_EX_TOOLWINDOW;
+ }
+ }
+
+ if ((WM_STYLE_INITIAL & WM_STYLE_TRANSPARENT) ^
+ (wmPtr->styleFlags & WM_STYLE_TRANSPARENT)) {
+ exStyleChanged = 1;
+ if (wmPtr->styleFlags & WM_STYLE_TRANSPARENT) {
+ exStyle |= WS_EX_TRANSPARENT;
+ } else {
+ exStyle &= ~WS_EX_TRANSPARENT;
+ }
+ }
+
+ if (styleChanged) {
+ SetWindowLong(wmPtr->wrapper, GWL_STYLE, style);
+ }
+
+ if (exStyleChanged) {
+ SetWindowLong(wmPtr->wrapper, GWL_EXSTYLE, exStyle);
+ }
+ }
+
+ /*
* Force an initial transition from withdrawn to the real
* initial state.
*/
***************
*** 839,844 ****
--- 963,982 ----
}
/*
+ * Now, if we applied any changed styles, we need to get those
+ * changes noticed, and we have to do it after the window has
+ * been mapped. Why? Because otherwise the window might not
+ * appear, depending on the styles changed. Why? Because that's
+ * the way WinXX appears to work. Believe me, I experimented
+ * quite a bit with this.
+ */
+ if (styleChanged || exStyleChanged) {
+ SetWindowPos(wmPtr->wrapper, insertAfter, 0, 0, 0, 0,
+ SWP_NOMOVE | SWP_NOSIZE | SWP_FRAMECHANGED | SWP_NOACTIVATE |
+ (insertAfter == HWND_TOP ? SWP_NOZORDER : 0));
+ }
+
+ /*
* Set up menus on the wrapper if required.
*/
***************
*** 2134,2140 ****
}
goto updateGeom;
} else if ((c == 's') && (strncmp(argv[1], "state", length) == 0)
! && (length >= 2)) {
if ((argc < 3) || (argc > 4)) {
Tcl_AppendResult(interp, "wrong # arguments: must be \"",
argv[0], " state window ?state?\"", (char *) NULL);
--- 2272,2278 ----
}
goto updateGeom;
} else if ((c == 's') && (strncmp(argv[1], "state", length) == 0)
! && (length >= 3)) {
if ((argc < 3) || (argc > 4)) {
Tcl_AppendResult(interp, "wrong # arguments: must be \"",
argv[0], " state window ?state?\"", (char *) NULL);
***************
*** 2211,2216 ****
--- 2349,2517 ----
}
}
}
+ } else if ((c == 's') && (strncmp(argv[1], "style", length) == 0)
+ && (length >= 3)) {
+ if ((argc < 4) || (argc > 5)) {
+ Tcl_AppendResult(interp, "wrong # arguments: must be \"",
+ argv[0], " style window ?style? ?boolean?\"", (char *) NULL);
+ return TCL_ERROR;
+ }
+ c = argv[3][0];
+ length = strlen(argv[3]);
+
+ if (argc == 5) {
+ HWND insertAfter = HWND_TOP;
+ long oldstyle, newstyle, setflag, setstyle;
+ int boolean, nIndex, setit = 0;
+
+ if (Tcl_GetBoolean(interp, argv[4], &boolean) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ if (Tk_WindowId((Tk_Window) winPtr) == None) {
+ Tk_MakeWindowExist((Tk_Window) winPtr);
+ }
+ if ((c == 'c') && (strncmp(argv[3], "caption", length) == 0)) {
+ setit = (boolean != (wmPtr->styleFlags & WM_STYLE_CAPTION));
+ nIndex = GWL_STYLE;
+ setstyle = WS_CAPTION;
+ setflag = WM_STYLE_CAPTION;
+ } else if ((c == 'd') && (strncmp(argv[3], "dialog", length) == 0)) {
+ setit = (boolean != (wmPtr->styleFlags & WM_STYLE_DIALOG));
+ nIndex = GWL_EXSTYLE;
+ setstyle = WS_EX_DLGMODALFRAME;
+ setflag = WM_STYLE_DIALOG;
+ } else if ((c == 'm') && (length >= 2) &&
+ (strncmp(argv[3], "maximize", length) == 0)) {
+ setit = (boolean != (wmPtr->styleFlags & WM_STYLE_MAXIMIZE));
+ nIndex = GWL_STYLE;
+ setstyle = WS_MAXIMIZEBOX;
+ setflag = WM_STYLE_MAXIMIZE;
+ } else if ((c == 'm') && (length >= 2) &&
+ (strncmp(argv[3], "minimize", length) == 0)) {
+ setit = (boolean != (wmPtr->styleFlags & WM_STYLE_MINIMIZE));
+ nIndex = GWL_STYLE;
+ setstyle = WS_MINIMIZEBOX;
+ setflag = WM_STYLE_MINIMIZE;
+ } else if ((c == 's') && (length >= 2) &&
+ (strncmp(argv[3], "stayontop", length) == 0)) {
+ setit = (boolean != (wmPtr->styleFlags & WM_STYLE_STAYONTOP));
+ nIndex = GWL_EXSTYLE;
+ setstyle = WS_EX_TOPMOST;
+ setflag = WM_STYLE_STAYONTOP;
+ insertAfter = boolean ? HWND_TOPMOST : HWND_NOTOPMOST;
+ } else if ((c == 's') && (length >= 2) &&
+ (strncmp(argv[3], "sysmenu", length) == 0)) {
+ setit = (boolean != (wmPtr->styleFlags & WM_STYLE_SYSMENU));
+ nIndex = GWL_STYLE;
+ setstyle = WS_SYSMENU;
+ setflag = WM_STYLE_SYSMENU;
+ } else if ((c == 't') && (length >= 2) &&
+ (strncmp(argv[3], "taskbar", length) == 0)) {
+ /*
+ * Note: for this to take effect, the use must withdraw
+ * the window, change the style, and deiconify the window.
+ */
+ setit = (boolean != (wmPtr->styleFlags & WM_STYLE_TASKBAR));
+ nIndex = GWL_EXSTYLE;
+ setstyle = WS_EX_TOOLWINDOW;
+ setflag = WM_STYLE_TASKBAR;
+ } else if ((c == 't') && (length >= 2) &&
+ (strncmp(argv[3], "transparent", length) == 0)) {
+ setit = (boolean != (wmPtr->styleFlags & WM_STYLE_TRANSPARENT));
+ nIndex = GWL_EXSTYLE;
+ setstyle = WS_EX_TRANSPARENT;
+ setflag = WM_STYLE_TRANSPARENT;
+ } else {
+ Tcl_AppendResult(interp, "bad argument \"", argv[3],
+ "\": must be caption, dialog, maximize, minimize, ",
+ "stayontop, sysmenu, taskbar, or transparent",
+ (char *) NULL);
+ return TCL_ERROR;
+ }
+ /* Update style flag setting */
+ if (boolean) {
+ wmPtr->styleFlags |= setflag;
+ } else {
+ wmPtr->styleFlags &= ~setflag;
+ }
+
+ /*
+ * Now update the window if the setting changed and it has
+ * already been mapped. We do the SetWindowPos to make sure
+ * frame changes get noticed in the cache. This is suggested
+ * to be done for any changes to the frame, and is required
+ * for stayontop, due to the specific insertAfter setting.
+ */
+ if (setit && !(wmPtr->flags & WM_NEVER_MAPPED) && wmPtr->wrapper) {
+ oldstyle = GetWindowLong(wmPtr->wrapper, nIndex);
+ if (boolean) {
+ if (setflag == WM_STYLE_TASKBAR) {
+ newstyle = oldstyle & ~setstyle;
+ } else {
+ newstyle = oldstyle | setstyle;
+ }
+ } else {
+ if (setflag == WM_STYLE_TASKBAR) {
+ newstyle = oldstyle | setstyle;
+ } else {
+ newstyle = oldstyle & ~setstyle;
+ }
+ }
+ SetWindowLong(wmPtr->wrapper, nIndex, newstyle);
+ SetWindowPos(wmPtr->wrapper, insertAfter, 0, 0, 0, 0,
+ SWP_NOMOVE | SWP_NOSIZE | SWP_FRAMECHANGED | SWP_NOACTIVATE |
+ (insertAfter == HWND_TOP ? SWP_NOZORDER : 0));
+ }
+
+ } else {
+ if ((c == 'c') &&
+ (strncmp(argv[3], "caption", length) == 0)) {
+ Tcl_SetBooleanObj(Tcl_GetObjResult(interp),
+ (wmPtr->styleFlags & WM_STYLE_CAPTION));
+ return TCL_OK;
+ } else if ((c == 'd') &&
+ (strncmp(argv[3], "dialog", length) == 0)) {
+ Tcl_SetBooleanObj(Tcl_GetObjResult(interp),
+ (wmPtr->styleFlags & WM_STYLE_DIALOG));
+ return TCL_OK;
+ } else if ((c == 'm') && (length >= 2) &&
+ (strncmp(argv[3], "maximize", length) == 0)) {
+ Tcl_SetBooleanObj(Tcl_GetObjResult(interp),
+ (wmPtr->styleFlags & WM_STYLE_MAXIMIZE));
+ return TCL_OK;
+ } else if ((c == 'm') && (length >= 2) &&
+ (strncmp(argv[3], "minimize", length) == 0)) {
+ Tcl_SetBooleanObj(Tcl_GetObjResult(interp),
+ (wmPtr->styleFlags & WM_STYLE_MINIMIZE));
+ return TCL_OK;
+ } else if ((c == 's') && (length >= 2) &&
+ (strncmp(argv[3], "stayontop", length) == 0)) {
+ Tcl_SetBooleanObj(Tcl_GetObjResult(interp),
+ (wmPtr->styleFlags & WM_STYLE_STAYONTOP));
+ return TCL_OK;
+ } else if ((c == 's') && (length >= 2) &&
+ (strncmp(argv[3], "sysmenu", length) == 0)) {
+ Tcl_SetBooleanObj(Tcl_GetObjResult(interp),
+ (wmPtr->styleFlags & WM_STYLE_SYSMENU));
+ return TCL_OK;
+ } else if ((c == 't') && (length >= 2) &&
+ (strncmp(argv[3], "taskbar", length) == 0)) {
+ Tcl_SetBooleanObj(Tcl_GetObjResult(interp),
+ (wmPtr->styleFlags & WM_STYLE_TASKBAR));
+ return TCL_OK;
+ } else if ((c == 't') && (length >= 2) &&
+ (strncmp(argv[3], "transparent", length) == 0)) {
+ Tcl_SetBooleanObj(Tcl_GetObjResult(interp),
+ (wmPtr->styleFlags & WM_STYLE_TRANSPARENT));
+ return TCL_OK;
+ } else {
+ Tcl_AppendResult(interp, "bad argument \"", argv[3],
+ "\": must be caption, dialog, maximize, minimize, ",
+ "stayontop, sysmenu, taskbar, or transparent",
+ (char *) NULL);
+ return TCL_ERROR;
+ }
+ }
} else if ((c == 't') && (strncmp(argv[1], "title", length) == 0)
&& (length >= 2)) {
if (argc > 4) {
***************
*** 2313,2320 ****
"focusmodel, frame, geometry, grid, group, iconbitmap, ",
"iconify, iconmask, iconname, iconposition, ",
"iconwindow, maxsize, minsize, overrideredirect, ",
! "positionfrom, protocol, resizable, sizefrom, state, title, ",
! "transient, or withdraw",
(char *) NULL);
return TCL_ERROR;
}
--- 2614,2621 ----
"focusmodel, frame, geometry, grid, group, iconbitmap, ",
"iconify, iconmask, iconname, iconposition, ",
"iconwindow, maxsize, minsize, overrideredirect, ",
! "positionfrom, protocol, resizable, sizefrom, state, style, ",
! "title, transient, or withdraw",
(char *) NULL);
return TCL_ERROR;
}