diff options
author | patthoyts <patthoyts@users.sourceforge.net> | 2010-01-03 20:03:55 (GMT) |
---|---|---|
committer | patthoyts <patthoyts@users.sourceforge.net> | 2010-01-03 20:03:55 (GMT) |
commit | e732ca1eeb37060c866b1e0f32bb45eb0c27db5d (patch) | |
tree | 9697cfd7717518364e4ec9383241289742feb1fa /win/tkWinMenu.c | |
parent | 794905497922ded3485e12e88b23990af8d1d1fa (diff) | |
download | tk-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.c | 97 |
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); + } } /* |