summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog7
-rw-r--r--generic/tkMenu.h17
-rw-r--r--win/tkWinMenu.c97
3 files changed, 99 insertions, 22 deletions
diff --git a/ChangeLog b/ChangeLog
index 721d5ad..38f812e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,12 @@
2010-01-03 Pat Thoyts <patthoyts@users.sourceforge.net>
+ * generic/tkMenu.h: [Patch 2848897] Support the system keyboard
+ * win/tkWinMenu.c: cues option on Windows. This system parameter
+ hides the underlines on menu items unless the keyboard is used to
+ open the menu. (kovalenko, thoyts)
+
+2010-01-03 Pat Thoyts <patthoyts@users.sourceforge.net>
+
* library/tearoff.tcl: tearoff menus should be transient and use the
toolwindow style on Windows.
* tests/menu.test: menu tests using 'tkwait visibility' are unix only
diff --git a/generic/tkMenu.h b/generic/tkMenu.h
index 642958a..c304ee0 100644
--- a/generic/tkMenu.h
+++ b/generic/tkMenu.h
@@ -9,7 +9,7 @@
* See the file "license.terms" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tkMenu.h,v 1.14 2007/12/13 15:24:16 dgp Exp $
+ * RCS: @(#) $Id: tkMenu.h,v 1.14.2.1 2010/01/03 20:03:55 patthoyts Exp $
*/
#ifndef _TKMENU
@@ -50,6 +50,19 @@ enum compound {
};
/*
+ * Additional menu entry drawing parameters for Windows platform.
+ * DRAW_MENU_ENTRY_ARROW makes TkpDrawMenuEntry draw the arrow
+ * itself when cascade entry is disabled.
+ * DRAW_MENU_ENTRY_NOUNDERLINE forbids underline when ODS_NOACCEL
+ * is set, thus obeying the system-wide Windows UI setting.
+ */
+
+enum drawingParameters {
+ DRAW_MENU_ENTRY_ARROW = (1<<0),
+ DRAW_MENU_ENTRY_NOUNDERLINE = (1<<1)
+};
+
+/*
* One of the following data structures is kept for each entry of each menu
* managed by this file:
*/
@@ -548,7 +561,7 @@ MODULE_SCOPE void TkpDrawMenuEntry(TkMenuEntry *mePtr,
Drawable d, Tk_Font tkfont,
const Tk_FontMetrics *menuMetricsPtr, int x,
int y, int width, int height, int strictMotif,
- int drawArrow);
+ int drawingParameters);
MODULE_SCOPE void TkpMenuInit(void);
MODULE_SCOPE int TkpMenuNewEntry(TkMenuEntry *mePtr);
MODULE_SCOPE int TkpNewMenu(TkMenu *menuPtr);
diff --git a/win/tkWinMenu.c b/win/tkWinMenu.c
index 8e19e0a..44f144e 100644
--- a/win/tkWinMenu.c
+++ b/win/tkWinMenu.c
@@ -10,9 +10,11 @@
* See the file "license.terms" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tkWinMenu.c,v 1.59.2.4 2009/12/27 23:42:45 patthoyts Exp $
+ * RCS: @(#) $Id: tkWinMenu.c,v 1.59.2.5 2010/01/03 20:03:55 patthoyts Exp $
*/
+#define WINVER 0x0500 /* Requires Windows 2K definitions */
+#define _WIN32_WINNT 0x0500
#define OEMRESOURCE
#include "tkWinInt.h"
#include "tkMenu.h"
@@ -50,6 +52,34 @@
#define MENU_SYSTEM_MENU MENU_PLATFORM_FLAG1
#define MENU_RECONFIGURE_PENDING MENU_PLATFORM_FLAG2
+/*
+ * ODS_NOACCEL flag forbids drawing accelerator cues (i.e. underlining labels)
+ * on Windows 2000 and above. The ODS_NOACCEL define is missing from mingw32
+ * headers and undefined for _WIN32_WINNT < 0x0500 in Microsoft SDK. We might
+ * check for _WIN32_WINNT here, but I think it's not needed, as checking for
+ * this flag does no harm on even on NT: reserved bits should be zero, and in
+ * fact they are.
+ */
+
+#ifndef ODS_NOACCEL
+#define ODS_NOACCEL 0x100
+#endif
+#ifndef SPI_GETKEYBOARDCUES
+#define SPI_GETKEYBOARDCUES 0x100A
+#endif
+#ifndef WM_UPDATEUISTATE
+#define WM_UPDATEUISTATE 0x0128
+#endif
+#ifndef UIS_SET
+#define UIS_SET 1
+#endif
+#ifndef UIS_CLEAR
+#define UIS_CLEAR 2
+#endif
+#ifndef UISF_HIDEACCEL
+#define UISF_HIDEACCEL 2
+#endif
+
#ifndef WM_UNINITMENUPOPUP
#define WM_UNINITMENUPOPUP 0x0125
#endif
@@ -59,6 +89,8 @@ static int indicatorDimensions[2];
* menu entry. Calculated at init time to save
* time. */
+static BOOL showMenuAccelerators;
+
typedef struct ThreadSpecificData {
int inPostMenu; /* We cannot be re-entrant like X Windows. */
WORD lastCommandID; /* The last command ID we allocated. */
@@ -112,7 +144,7 @@ static void DrawMenuEntryIndicator(TkMenu *menuPtr,
static void DrawMenuEntryLabel(TkMenu *menuPtr, TkMenuEntry *mePtr,
Drawable d, GC gc, Tk_Font tkfont,
const Tk_FontMetrics *fmPtr, int x, int y,
- int width, int height);
+ int width, int height, int underline);
static void DrawMenuSeparator(TkMenu *menuPtr, TkMenuEntry *mePtr,
Drawable d, GC gc, Tk_Font tkfont,
const Tk_FontMetrics *fmPtr,
@@ -940,6 +972,13 @@ TkWinEmbeddedMenuProc(
nIdles = 0;
break;
+ case WM_SETTINGCHANGE:
+ if (wParam == SPI_SETNONCLIENTMETRICS
+ || wParam == SPI_SETKEYBOARDCUES) {
+ SetDefaults(0);
+ }
+ break;
+
case WM_INITMENU:
case WM_SYSCOMMAND:
case WM_COMMAND:
@@ -1165,11 +1204,14 @@ TkWinHandleMenuEvent(
TkWinDrawable *twdPtr;
LPDRAWITEMSTRUCT itemPtr = (LPDRAWITEMSTRUCT) *plParam;
Tk_FontMetrics fontMetrics;
- int drawArrow = 0;
+ int drawingParameters = 0;
if (itemPtr != NULL && tsdPtr->modalMenuPtr != NULL) {
Tk_Font tkfont;
+ if (itemPtr->itemState & ODS_NOACCEL && !showMenuAccelerators) {
+ drawingParameters |= DRAW_MENU_ENTRY_NOUNDERLINE;
+ }
mePtr = (TkMenuEntry *) itemPtr->itemData;
menuPtr = mePtr->menuPtr;
twdPtr = (TkWinDrawable *) ckalloc(sizeof(TkWinDrawable));
@@ -1198,12 +1240,12 @@ TkWinHandleMenuEvent(
}
/*
- * Also, set the drawArrow flag for a disabled cascade menu
- * since we need to draw the arrow ourselves.
+ * Also, set the DRAW_MENU_ENTRY_ARROW flag for a disabled
+ * cascade menu since we need to draw the arrow ourselves.
*/
if (mePtr->type == CASCADE_ENTRY) {
- drawArrow = 1;
+ drawingParameters |= DRAW_MENU_ENTRY_ARROW;
}
}
@@ -1212,7 +1254,8 @@ TkWinHandleMenuEvent(
TkpDrawMenuEntry(mePtr, (Drawable) twdPtr, tkfont, &fontMetrics,
itemPtr->rcItem.left, itemPtr->rcItem.top,
itemPtr->rcItem.right - itemPtr->rcItem.left,
- itemPtr->rcItem.bottom - itemPtr->rcItem.top, 0,drawArrow);
+ itemPtr->rcItem.bottom - itemPtr->rcItem.top,
+ 0, drawingParameters);
ckfree((char *) twdPtr);
}
@@ -2140,7 +2183,8 @@ DrawMenuEntryLabel(
int x, /* left edge */
int y, /* right edge */
int width, /* width of entry */
- int height) /* height of entry */
+ int height, /* height of entry */
+ int underline) /* accelerator cue should be drawn */
{
int indicatorSpace = mePtr->indicatorSpace;
int activeBorderWidth;
@@ -2285,8 +2329,10 @@ DrawMenuEntryLabel(
Tk_DrawChars(menuPtr->display, d, gc, tkfont, label,
mePtr->labelLength, leftEdge + textXOffset,
baseline + textYOffset);
- DrawMenuUnderline(menuPtr, mePtr, d, gc, tkfont, fmPtr,
- x + textXOffset, y + textYOffset, width, height);
+ if (underline) {
+ DrawMenuUnderline(menuPtr, mePtr, d, gc, tkfont, fmPtr,
+ x + textXOffset, y + textYOffset, width, height);
+ }
}
}
@@ -2443,9 +2489,9 @@ TkpDrawMenuEntry(
int width, /* Width of the entry rectangle */
int height, /* Height of the current rectangle */
int strictMotif, /* Boolean flag */
- int drawArrow) /* Whether or not to draw the cascade arrow
- * for cascade items. Only applies to
- * Windows. */
+ int drawingParameters) /* Whether or not to draw the cascade arrow
+ * for cascade items and accelerator
+ * cues. Only applies to Windows. */
{
GC gc, indicatorGC;
TkMenu *menuPtr = mePtr->menuPtr;
@@ -2566,12 +2612,13 @@ TkpDrawMenuEntry(
adjustedX, adjustedY, width, adjustedHeight);
} else {
DrawMenuEntryLabel(menuPtr, mePtr, d, gc, tkfont, fmPtr,
- adjustedX, adjustedY, width, adjustedHeight);
+ adjustedX, adjustedY, width, adjustedHeight,
+ (drawingParameters & DRAW_MENU_ENTRY_NOUNDERLINE)?0:1);
DrawMenuEntryAccelerator(menuPtr, mePtr, d, gc, tkfont, fmPtr,
activeBorder, adjustedX, adjustedY, width, adjustedHeight);
DrawMenuEntryArrow(menuPtr, mePtr, d, gc,
activeBorder, adjustedX, adjustedY, width, adjustedHeight,
- drawArrow);
+ (drawingParameters & DRAW_MENU_ENTRY_ARROW)?1:0);
if (!mePtr->hideMargin) {
DrawMenuEntryIndicator(menuPtr, mePtr, d, gc, indicatorGC, tkfont,
fmPtr, adjustedX, adjustedY, width, adjustedHeight);
@@ -3122,21 +3169,21 @@ TkWinGetMenuSystemDefault(
/*
*----------------------------------------------------------------------
*
- * TkWinMenuSetDefaults --
+ * SetDefaults --
*
- * Sets up the hash tables and the variables used by the menu package.
+ * Read system menu settings (font, sizes of items, use of accelerators)
+ * This is called if the UI theme or settings are changed.
*
* Results:
* None.
*
* Side effects:
- * lastMenuID gets initialized, and the parent hash and the command hash
- * are allocated.
+ * May result in menu items being redrawn with different appearance.
*
*----------------------------------------------------------------------
*/
-void
+static void
SetDefaults(
int firstTime) /* Is this the first time this has been
* called? */
@@ -3227,6 +3274,16 @@ SetDefaults(
indicatorDimensions[0] = HIWORD(dimensions);
indicatorDimensions[1] = LOWORD(dimensions);
}
+
+ /*
+ * Accelerators used to be always underlines until Win2K when a system
+ * parameter was introduced to hide them unless Alt is pressed.
+ */
+
+ showMenuAccelerators = TRUE;
+ if (TkWinGetPlatformId() == VER_PLATFORM_WIN32_NT) {
+ SystemParametersInfo(SPI_GETKEYBOARDCUES, 0, &showMenuAccelerators, 0);
+ }
}
/*