include/vcl/menu.hxx | 2 + vcl/inc/win/saldata.hxx | 1 vcl/inc/win/wincomp.hxx | 9 ------ vcl/source/window/menu.cxx | 41 ++++++++++++++++++++++++++++++- vcl/source/window/menubarwindow.cxx | 29 +++++++++++++++++++++ vcl/source/window/menubarwindow.hxx | 6 ++++ vcl/source/window/menufloatingwindow.cxx | 15 +++++++++++ vcl/source/window/syswin.cxx | 13 ++++++++- vcl/win/app/saldata.cxx | 25 ------------------ vcl/win/window/salframe.cxx | 34 ++++++------------------- 10 files changed, 110 insertions(+), 65 deletions(-)
New commits: commit f2dfb95258215f90562617823b950c3ed151c1bf Author: Mike Kaganski <[email protected]> AuthorDate: Sat Feb 10 18:49:55 2024 +0600 Commit: Mike Kaganski <[email protected]> CommitDate: Sat Feb 10 16:58:03 2024 +0100 tdf#54169: revert "gtk is the only case auto-accel is true, and the ... menubar is native gtk there" (commit 3fbae5dc7e7b200776bbc8a7c2a43e1e04f15a2b from 2021-08-05). This will be needed for auto-accel on Windows. Change-Id: Ie37de17e35658a0f7c748d3c9dd923dba954298c Reviewed-on: https://gerrit.libreoffice.org/c/core/+/163214 Tested-by: Mike Kaganski <[email protected]> Reviewed-by: Mike Kaganski <[email protected]> diff --git a/include/vcl/menu.hxx b/include/vcl/menu.hxx index a28182e51fe2..9629a5fef39d 100644 --- a/include/vcl/menu.hxx +++ b/include/vcl/menu.hxx @@ -45,6 +45,7 @@ class MenuItemList; class Image; class PopupMenu; class KeyEvent; +class CommandEvent; class MenuFloatingWindow; class SalMenu; class MenuBarWindow; @@ -427,6 +428,7 @@ class VCL_DLLPUBLIC MenuBar final : public Menu SAL_DLLPRIVATE static VclPtr<vcl::Window> ImplCreate(vcl::Window* pParent, vcl::Window* pWindow, MenuBar* pMenu); SAL_DLLPRIVATE static void ImplDestroy(MenuBar* pMenu, bool bDelete); SAL_DLLPRIVATE bool ImplHandleKeyEvent(const KeyEvent& rKEvent); + SAL_DLLPRIVATE bool ImplHandleCmdEvent(const CommandEvent& rCEvent); /// Return the MenuBarWindow. MenuBarWindow* getMenuBarWindow(); diff --git a/vcl/source/window/menu.cxx b/vcl/source/window/menu.cxx index 387d74b0d1b3..b72f2f8c8091 100644 --- a/vcl/source/window/menu.cxx +++ b/vcl/source/window/menu.cxx @@ -1948,7 +1948,13 @@ void Menu::ImplPaint(vcl::RenderContext& rRenderContext, Size const & rSize, aTmpPos.setX( aPos.X() + nTextPos ); aTmpPos.setY( aPos.Y() ); aTmpPos.AdjustY(nTextOffsetY ); - DrawTextFlags nStyle = nTextStyle | DrawTextFlags::Mnemonic; + DrawTextFlags nStyle = nTextStyle; + + const Menu *pMenu = this; + while (!pMenu->IsMenuBar() && pMenu->pStartedFrom) + pMenu = pMenu->pStartedFrom; + if (!pMenu->IsMenuBar() || !static_cast<MenuBarWindow*>(pMenu->pWindow.get())->GetMBWHideAccel()) + nStyle |= DrawTextFlags::Mnemonic; if (pData->bIsTemporary) nStyle |= DrawTextFlags::Disable; @@ -2546,6 +2552,32 @@ bool MenuBar::ImplHandleKeyEvent( const KeyEvent& rKEvent ) return bDone; } +bool MenuBar::ImplHandleCmdEvent( const CommandEvent& rCEvent ) +{ + // No keyboard processing when system handles the menu or our menubar is invisible + if( !IsDisplayable() || + ( ImplGetSalMenu() && ImplGetSalMenu()->VisibleMenuBar() ) ) + return false; + + // check for enabled, if this method is called from another window... + MenuBarWindow* pWin = static_cast<MenuBarWindow*>(ImplGetWindow()); + if ( pWin && pWin->IsEnabled() && pWin->IsInputEnabled() && ! pWin->IsInModalMode() ) + { + if (rCEvent.GetCommand() == CommandEventId::ModKeyChange && ImplGetSVData()->maNWFData.mbAutoAccel) + { + const CommandModKeyData* pCData = rCEvent.GetModKeyData (); + if (pWin->m_nHighlightedItem == ITEMPOS_INVALID) + { + if (pCData && pCData->IsMod2() && pCData->IsDown()) + pWin->SetMBWHideAccel(false); + pWin->Invalidate(InvalidateFlags::Update); + } + return true; + } + } + return false; +} + void MenuBar::SelectItem(sal_uInt16 nId) { if (!pWindow) @@ -2829,6 +2861,13 @@ bool PopupMenu::PrepareRun(const VclPtr<vcl::Window>& pParentWin, tools::Rectang if (!pSFrom && (vcl::IsInPopupMenuExecute() || !nItemCount)) return false; + // set the flag to hide or show accelerators in the menu depending on whether the menu was launched by mouse or keyboard shortcut + if( pSFrom && pSFrom->IsMenuBar()) + { + auto pMenuBarWindow = static_cast<MenuBarWindow*>(pSFrom->pWindow.get()); + pMenuBarWindow->SetMBWHideAccel( !(pMenuBarWindow->GetMBWMenuKey()) ); + } + mpLayoutData.reset(); ImplSVData* pSVData = ImplGetSVData(); diff --git a/vcl/source/window/menubarwindow.cxx b/vcl/source/window/menubarwindow.cxx index 8e2bc8d7ebe2..4198c5a824c3 100644 --- a/vcl/source/window/menubarwindow.cxx +++ b/vcl/source/window/menubarwindow.cxx @@ -124,6 +124,8 @@ MenuBarWindow::MenuBarWindow( vcl::Window* pParent ) : m_nRolloveredItem = ITEMPOS_INVALID; mbAutoPopup = true; m_bIgnoreFirstMove = true; + SetMBWHideAccel(true); + SetMBWMenuKey(false); m_aCloseBtn->maImage = Image(StockImage::Yes, SV_RESID_BITMAP_CLOSEDOC); @@ -390,6 +392,7 @@ void MenuBarWindow::PopupClosed( Menu const * pPopup ) void MenuBarWindow::MouseButtonDown( const MouseEvent& rMEvt ) { mbAutoPopup = true; + SetMBWMenuKey(false); sal_uInt16 nEntry = ImplFindEntry( rMEvt.GetPosPixel() ); if ( ( nEntry != ITEMPOS_INVALID ) && !m_pActivePopup ) { @@ -414,7 +417,18 @@ void MenuBarWindow::MouseMove( const MouseEvent& rMEvt ) if ( rMEvt.IsLeaveWindow() ) { if ( m_nRolloveredItem != ITEMPOS_INVALID && m_nRolloveredItem != m_nHighlightedItem ) - Invalidate(); //HighlightItem( nRolloveredItem, false ); + { + // there is a spurious MouseMove generated after a menu is launched from the keyboard, hence this... + if (m_nHighlightedItem != ITEMPOS_INVALID) + { + bool hide = GetMBWHideAccel(); + SetMBWHideAccel(true); + Invalidate(); //HighlightItem( nRolloveredItem, false ); + SetMBWHideAccel(hide); + } + else + Invalidate(); //HighlightItem( nRolloveredItem, false ); + } m_nRolloveredItem = ITEMPOS_INVALID; return; @@ -451,6 +465,8 @@ void MenuBarWindow::ChangeHighlightItem( sal_uInt16 n, bool bSelectEntry, bool b if( ! m_pMenu ) return; + SetMBWHideAccel(n == ITEMPOS_INVALID); + // #57934# close active popup if applicable, as TH's background storage works. MenuItemData* pNextData = m_pMenu->pItemList->GetDataFromPos( n ); if ( m_pActivePopup && m_pActivePopup->ImplGetWindow() && ( !pNextData || ( m_pActivePopup != pNextData->pSubMenu ) ) ) @@ -834,6 +850,8 @@ bool MenuBarWindow::HandleKeyEvent( const KeyEvent& rKEvent, bool bFromMenu ) } } + bool autoacc = ImplGetSVData()->maNWFData.mbAutoAccel; + if ( !bDone && ( bFromMenu || rKEvent.GetKeyCode().IsMod2() ) ) { sal_Unicode nCharCode = rKEvent.GetCharCode(); @@ -850,6 +868,15 @@ bool MenuBarWindow::HandleKeyEvent( const KeyEvent& rKEvent, bool bFromMenu ) } } + const bool bShowAccels = nCode != KEY_ESCAPE; + if (GetMBWMenuKey() != bShowAccels) + { + SetMBWMenuKey(bShowAccels); + SetMBWHideAccel(!bShowAccels); + if (autoacc) + Invalidate(InvalidateFlags::Update); + } + return bDone; } diff --git a/vcl/source/window/menubarwindow.hxx b/vcl/source/window/menubarwindow.hxx index b5f026254ddd..b2bced40d05c 100644 --- a/vcl/source/window/menubarwindow.hxx +++ b/vcl/source/window/menubarwindow.hxx @@ -76,6 +76,8 @@ private: VclPtr<vcl::Window> m_xSaveFocusId; bool mbAutoPopup; bool m_bIgnoreFirstMove; + bool mbHideAccel; + bool mbMenuKey; VclPtr<DecoToolBox> m_aCloseBtn; VclPtr<PushButton> m_aFloatBtn; @@ -136,6 +138,10 @@ public: tools::Rectangle GetMenuBarButtonRectPixel(sal_uInt16 nId); void RemoveMenuBarButton(sal_uInt16 nId); bool HandleMenuButtonEvent(sal_uInt16 i_nButtonId); + void SetMBWHideAccel(bool val) { mbHideAccel = val; } + bool GetMBWHideAccel() const { return mbHideAccel; } + void SetMBWMenuKey(bool val) { mbMenuKey = val; } + bool GetMBWMenuKey() const { return mbMenuKey; } bool CanGetFocus() const; }; diff --git a/vcl/source/window/menufloatingwindow.cxx b/vcl/source/window/menufloatingwindow.cxx index 95a0d3f4d02a..c46dcede0b53 100644 --- a/vcl/source/window/menufloatingwindow.cxx +++ b/vcl/source/window/menufloatingwindow.cxx @@ -19,6 +19,7 @@ #include "menufloatingwindow.hxx" #include "menuitemlist.hxx" +#include "menubarwindow.hxx" #include "bufferdevice.hxx" #include <sal/log.hxx> @@ -1031,6 +1032,7 @@ void MenuFloatingWindow::KeyInput( const KeyEvent& rKEvent ) { VclPtr<vcl::Window> xWindow = this; + bool autoacc = ImplGetSVData()->maNWFData.mbAutoAccel; sal_uInt16 nCode = rKEvent.GetKeyCode().GetCode(); bKeyInput = true; switch ( nCode ) @@ -1177,6 +1179,19 @@ void MenuFloatingWindow::KeyInput( const KeyEvent& rKEvent ) } } + if (pMenu && pMenu->pStartedFrom && pMenu->pStartedFrom->IsMenuBar()) + { + MenuBar *pMenuBar = static_cast<MenuBar*>(pMenu->pStartedFrom.get()); + const bool bShowAccels = nCode != KEY_ESCAPE; + if (pMenuBar->getMenuBarWindow()->GetMBWMenuKey() != bShowAccels) + { + pMenuBar->getMenuBarWindow()->SetMBWMenuKey(bShowAccels); + pMenuBar->getMenuBarWindow()->SetMBWHideAccel(!bShowAccels); + if (autoacc) + Invalidate(InvalidateFlags::Update); + } + } + // #105474# check if menu window was not destroyed if ( !xWindow->isDisposed() ) { diff --git a/vcl/source/window/syswin.cxx b/vcl/source/window/syswin.cxx index 6584c1e3b04c..4cf822d770fe 100644 --- a/vcl/source/window/syswin.cxx +++ b/vcl/source/window/syswin.cxx @@ -179,7 +179,8 @@ bool SystemWindow::EventNotify( NotifyEvent& rNEvt ) ToggleMnemonicsOnHierarchy(*rNEvt.GetCommandEvent(), this); // capture KeyEvents for menu handling - if (rNEvt.GetType() == NotifyEventType::KEYINPUT) + if (rNEvt.GetType() == NotifyEventType::KEYINPUT || + rNEvt.GetType() == NotifyEventType::COMMAND) { MenuBar* pMBar = mpMenuBar; if ( !pMBar && ( GetType() == WindowType::FLOATINGWINDOW ) ) @@ -188,7 +189,15 @@ bool SystemWindow::EventNotify( NotifyEvent& rNEvt ) if( pWin && pWin->IsSystemWindow() ) pMBar = static_cast<SystemWindow*>(pWin)->GetMenuBar(); } - if (pMBar && pMBar->ImplHandleKeyEvent(*rNEvt.GetKeyEvent())) + bool bDone(false); + if (pMBar) + { + if (rNEvt.GetType() == NotifyEventType::COMMAND) + bDone = pMBar->ImplHandleCmdEvent(*rNEvt.GetCommandEvent()); + else + bDone = pMBar->ImplHandleKeyEvent(*rNEvt.GetKeyEvent()); + } + if (bDone) return true; } commit 25bd3e444e4f8bbe1ca83b21a76daef1695a51dc Author: Mike Kaganski <[email protected]> AuthorDate: Sat Feb 10 18:59:55 2024 +0600 Commit: Mike Kaganski <[email protected]> CommitDate: Sat Feb 10 16:57:56 2024 +0100 Drop obsolete handling of wheel mouse Change-Id: I9958e69c953563285577f5cdea220371af4848d7 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/163213 Tested-by: Jenkins Reviewed-by: Mike Kaganski <[email protected]> diff --git a/vcl/inc/win/wincomp.hxx b/vcl/inc/win/wincomp.hxx index 4383bc5b77cc..e326a504e35b 100644 --- a/vcl/inc/win/wincomp.hxx +++ b/vcl/inc/win/wincomp.hxx @@ -169,13 +169,4 @@ inline HINSTANCE GetWindowInstance( HWND hWnd ) return reinterpret_cast<HINSTANCE>(GetWindowLongPtrW( hWnd, GWLP_HINSTANCE )); } - -#define MOUSEZ_CLASSNAME L"MouseZ" // wheel window class -#define MOUSEZ_TITLE L"Magellan MSWHEEL" // wheel window title - -#define MSH_WHEELMODULE_CLASS (MOUSEZ_CLASSNAME) -#define MSH_WHEELMODULE_TITLE (MOUSEZ_TITLE) - -#define MSH_SCROLL_LINES L"MSH_SCROLL_LINES_MSG" - /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/win/window/salframe.cxx b/vcl/win/window/salframe.cxx index f1844f43da54..ed8f7fddee7a 100644 --- a/vcl/win/window/salframe.cxx +++ b/vcl/win/window/salframe.cxx @@ -719,18 +719,7 @@ const sal_uInt16 aImplTranslateKeyTab[KEY_TAB_SIZE] = static UINT ImplSalGetWheelScrollLines() { UINT nScrLines = 0; - HWND hWndMsWheel = FindWindowW( MSH_WHEELMODULE_CLASS, MSH_WHEELMODULE_TITLE ); - if ( hWndMsWheel ) - { - UINT nGetScrollLinesMsgId = RegisterWindowMessageW( MSH_SCROLL_LINES ); - nScrLines = static_cast<UINT>(SendMessageW( hWndMsWheel, nGetScrollLinesMsgId, 0, 0 )); - } - - if ( !nScrLines ) - if( !SystemParametersInfoW( SPI_GETWHEELSCROLLLINES, 0, &nScrLines, 0 ) ) - nScrLines = 0 ; - - if ( !nScrLines ) + if (!SystemParametersInfoW(SPI_GETWHEELSCROLLLINES, 0, &nScrLines, 0) || !nScrLines) nScrLines = 3; return nScrLines; commit 2790acbb29f8d5f180cd86d924c1e991e7d854df Author: Mike Kaganski <[email protected]> AuthorDate: Sat Feb 10 18:56:50 2024 +0600 Commit: Mike Kaganski <[email protected]> CommitDate: Sat Feb 10 16:57:50 2024 +0100 Simplify a bit Use existing rtl_ustr_ascii_compareIgnoreAsciiCase, instead of inventing an own local comparison function. And standardize on WM_SETTINGCHANGE, which is the same as WM_WININICHANGE. Change-Id: Ifaf1f73066edf7d553174b529be5aa55179ae92e Reviewed-on: https://gerrit.libreoffice.org/c/core/+/163212 Tested-by: Jenkins Reviewed-by: Mike Kaganski <[email protected]> diff --git a/vcl/inc/win/saldata.hxx b/vcl/inc/win/saldata.hxx index 80acfaabec31..607788fbd34f 100644 --- a/vcl/inc/win/saldata.hxx +++ b/vcl/inc/win/saldata.hxx @@ -188,7 +188,6 @@ void ImplSalLogFontToFontW( HDC hDC, const LOGFONTW& rLogFont, vcl::Font& rFont rtl_TextEncoding ImplSalGetSystemEncoding(); OUString ImplSalGetUniString(const char* pStr, sal_Int32 nLen = -1); -int ImplSalWICompareAscii( const wchar_t* pStr1, const char* pStr2 ); #define SAL_FRAME_WNDEXTRA sizeof( DWORD ) #define SAL_FRAME_THIS GWLP_USERDATA diff --git a/vcl/win/app/saldata.cxx b/vcl/win/app/saldata.cxx index 31fa661636f8..583a59bb6c1b 100644 --- a/vcl/win/app/saldata.cxx +++ b/vcl/win/app/saldata.cxx @@ -49,30 +49,5 @@ OUString ImplSalGetUniString(const char* pStr, sal_Int32 const nLen) RTL_TEXTTOUNICODE_FLAGS_INVALID_DEFAULT ); } -int ImplSalWICompareAscii( const wchar_t* pStr1, const char* pStr2 ) -{ - int nRet; - char c2; - do - { - // change to LowerCase if the char is between 'A' and 'Z' - wchar_t c1 = *pStr1; - c2 = *pStr2; - if ( (c1 >= 65) && (c1 <= 90) ) - c1 += 32; - if ( (c2 >= 65) && (c2 <= 90) ) - c2 += 32; - nRet = static_cast<sal_Int32>(c1)- static_cast<sal_Int32>(static_cast<unsigned char>(c2)); - if ( nRet != 0 ) - break; - - pStr1++; - pStr2++; - } - while ( c2 ); - - return nRet; -} - /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/win/window/salframe.cxx b/vcl/win/window/salframe.cxx index 1eed596e6c3d..f1844f43da54 100644 --- a/vcl/win/window/salframe.cxx +++ b/vcl/win/window/salframe.cxx @@ -4368,8 +4368,7 @@ static bool ImplHandleShutDownMsg( HWND hWnd ) return nRet; } -static void ImplHandleSettingsChangeMsg( HWND hWnd, UINT nMsg, - WPARAM wParam, LPARAM lParam ) +static void ImplHandleSettingsChangeMsg(HWND hWnd, UINT nMsg, WPARAM /*wParam*/, LPARAM lParam) { SalEvent nSalEvent = SalEvent::SettingsChanged; @@ -4379,21 +4378,15 @@ static void ImplHandleSettingsChangeMsg( HWND hWnd, UINT nMsg, nSalEvent = SalEvent::DisplayChanged; else if ( nMsg == WM_FONTCHANGE ) nSalEvent = SalEvent::FontChanged; - else if ( nMsg == WM_WININICHANGE ) + else if ( nMsg == WM_SETTINGCHANGE ) { - if ( lParam ) + if (const auto* paramStr = o3tl::toU(reinterpret_cast<const wchar_t*>(lParam))) { - if ( ImplSalWICompareAscii( reinterpret_cast<const wchar_t*>(lParam), "devices" ) == 0 ) + if (rtl_ustr_ascii_compareIgnoreAsciiCase(paramStr, "devices") == 0) nSalEvent = SalEvent::PrinterChanged; } - } - - if ( nMsg == WM_SETTINGCHANGE ) - { - if ( wParam == SPI_SETWHEELSCROLLLINES ) - aSalShlData.mnWheelScrollLines = ImplSalGetWheelScrollLines(); - else if( wParam == SPI_SETWHEELSCROLLCHARS ) - aSalShlData.mnWheelScrollChars = ImplSalGetWheelScrollChars(); + aSalShlData.mnWheelScrollLines = ImplSalGetWheelScrollLines(); + aSalShlData.mnWheelScrollChars = ImplSalGetWheelScrollChars(); UpdateDarkMode(hWnd); GetSalData()->mbThemeChanged = true; } @@ -4405,7 +4398,7 @@ static void ImplHandleSettingsChangeMsg( HWND hWnd, UINT nMsg, if (!pFrame) return; - if (((nMsg == WM_DISPLAYCHANGE) || (nMsg == WM_WININICHANGE)) && pFrame->isFullScreen()) + if (((nMsg == WM_DISPLAYCHANGE) || (nMsg == WM_SETTINGCHANGE)) && pFrame->isFullScreen()) ImplSalFrameFullScreenPos(pFrame); pFrame->CallCallback(nSalEvent, nullptr);
