summaryrefslogtreecommitdiffstats
path: root/win/tkWinMenu.c
diff options
context:
space:
mode:
authorpatthoyts <patthoyts@users.sourceforge.net>2010-01-03 20:03:55 (GMT)
committerpatthoyts <patthoyts@users.sourceforge.net>2010-01-03 20:03:55 (GMT)
commite732ca1eeb37060c866b1e0f32bb45eb0c27db5d (patch)
tree9697cfd7717518364e4ec9383241289742feb1fa /win/tkWinMenu.c
parent794905497922ded3485e12e88b23990af8d1d1fa (diff)
downloadtk-e732ca1eeb37060c866b1e0f32bb45eb0c27db5d.zip
tk-e732ca1eeb37060c866b1e0f32bb45eb0c27db5d.tar.gz
tk-e732ca1eeb37060c866b1e0f32bb45eb0c27db5d.tar.bz2
Patch 2848897: Support the system keyboard cues setting on Windows
Backported this patch from HEAD (kovalenko, thoyts)
Diffstat (limited to 'win/tkWinMenu.c')
-rw-r--r--win/tkWinMenu.c97
1 files changed, 77 insertions, 20 deletions
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);
+ }
}
/*