sfx2/source/appl/appcfg.cxx | 2 sfx2/source/appl/shutdownicon.cxx | 9 sfx2/source/appl/shutdowniconaqua.mm | 382 +++++++++++++++++++++++++++++++++-- sfx2/source/appl/shutdowniconw32.cxx | 2 sfx2/source/dialog/backingcomp.cxx | 10 sfx2/source/inc/shutdownicon.hxx | 7 solenv/clang-format/excludelist | 2 vcl/inc/osx/vclnsapp.h | 1 vcl/osx/vclnsapp.mm | 11 + 9 files changed, 406 insertions(+), 20 deletions(-)
New commits: commit 05e78507e0e26886c04fdf02aba97c5fdc9060d3 Author: Patrick Luby <guibmac...@gmail.com> AuthorDate: Wed Jan 8 20:51:38 2025 -0500 Commit: Adolfo Jayme Barrientos <fit...@ubuntu.com> CommitDate: Tue Jan 14 10:16:01 2025 +0100 tdf#41775 copy the Start Center menubar to the default menubar on macOS The ShutdownIcon class on macOS handles the menubar for when there are no windows displayed. So copy the entire menubar's tree to a native menu and use that native menu as the default menubar. Note: not all menu items may crash without a C++ window so currently the Tools > Configure menu must force the Start Center window to reappear before displaying its dialog. Change-Id: I3190da0dffdd6c7181939aec71954e067689d081 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/179980 Tested-by: Jenkins Reviewed-by: Patrick Luby <guibomac...@gmail.com> (cherry picked from commit 6efdd1444810e132ba37379dd39afa6a3220f541) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/180188 Reviewed-by: Adolfo Jayme Barrientos <fit...@ubuntu.com> diff --git a/sfx2/source/appl/appcfg.cxx b/sfx2/source/appl/appcfg.cxx index 074ad93b6f74..ba200d4d5368 100644 --- a/sfx2/source/appl/appcfg.cxx +++ b/sfx2/source/appl/appcfg.cxx @@ -49,7 +49,7 @@ #include <sfx2/objsh.hxx> #include <comphelper/lok.hxx> #include <objshimp.hxx> -#include "shutdownicon.hxx" +#include <shutdownicon.hxx> using namespace ::com::sun::star::uno; diff --git a/sfx2/source/appl/shutdownicon.cxx b/sfx2/source/appl/shutdownicon.cxx index b16be15bcf70..ca15df227465 100644 --- a/sfx2/source/appl/shutdownicon.cxx +++ b/sfx2/source/appl/shutdownicon.cxx @@ -20,7 +20,7 @@ #include <sal/config.h> #include <sal/log.hxx> -#include "shutdownicon.hxx" +#include <shutdownicon.hxx> #include <sfx2/strings.hrc> #include <sfx2/app.hxx> #include <svtools/imagemgr.hxx> @@ -203,6 +203,11 @@ void ShutdownIcon::FileOpen() void ShutdownIcon::FromTemplate() +{ + ShutdownIcon::FromCommand( ".uno:NewDoc" ); +} + +void ShutdownIcon::FromCommand( const OUString& rCommand ) { if ( !getInstance() || !getInstance()->m_xDesktop.is() ) return; @@ -213,7 +218,7 @@ void ShutdownIcon::FromTemplate() xFrame = xDesktop; URL aTargetURL; - aTargetURL.Complete = ".uno:NewDoc"; + aTargetURL.Complete = rCommand; css::uno::Reference< util::XURLTransformer > xTrans( util::URLTransformer::create( ::comphelper::getProcessComponentContext() ) ); xTrans->parseStrict( aTargetURL ); diff --git a/sfx2/source/appl/shutdowniconaqua.mm b/sfx2/source/appl/shutdowniconaqua.mm index 6b519fcefbe9..9e037fe5726e 100644 --- a/sfx2/source/appl/shutdowniconaqua.mm +++ b/sfx2/source/appl/shutdowniconaqua.mm @@ -21,6 +21,7 @@ #include <unotools/moduleoptions.hxx> #include <unotools/dynamicmenuoptions.hxx> #include <unotools/historyoptions.hxx> +#include <officecfg/Office/Common.hxx> #include <rtl/ustring.hxx> #include <tools/urlobj.hxx> #include <osl/file.h> @@ -31,7 +32,10 @@ #include <sfx2/sfxresid.hxx> #include <sfx2/strings.hrc> #include <vcl/svapp.hxx> -#include "shutdownicon.hxx" +#include <vcl/mnemonic.hxx> +#include <vcl/image.hxx> +#include <svtools/imagemgr.hxx> +#include <shutdownicon.hxx> #include <com/sun/star/util/XStringWidth.hpp> @@ -55,6 +59,8 @@ #define MI_TEMPLATE 8 #define MI_STARTMODULE 9 +#define UNO_TOGGLECURRENTMODULE_COMMAND ".uno:ToggleCurrentModule" + @interface QSMenuExecute : NSObject { } @@ -65,6 +71,8 @@ @implementation QSMenuExecute -(void)executeMenuItem: (NSMenuItem*)pItem { + SolarMutexGuard aGuard; + switch( [pItem tag] ) { case MI_OPEN: @@ -102,6 +110,9 @@ -(void)dockIconClicked: (NSObject*)pSender { (void)pSender; + + SolarMutexGuard aGuard; + // start module ShutdownIcon::OpenURL( STARTMODULE_URL, "_default" ); } @@ -113,6 +124,7 @@ bool ShutdownIcon::IsQuickstarterInstalled() return true; } +static NSArray<NSMenuItem*>* pPreferredMenus = nil; static NSMenuItem* pDefMenu = nil, *pDockSubMenu = nil; static QSMenuExecute* pExecute = nil; @@ -147,6 +159,63 @@ class RecentFilesStringLength : public ::cppu::WeakImplHelper< css::util::XStrin } +@interface QSCommandMenuItem : NSMenuItem +{ + OUString m_aCommand; +} +-(void)menuItemTriggered: (id)aSender; +-(void)setCommand: (OUString)aCommand; +@end + +@implementation QSCommandMenuItem + +-(void)menuItemTriggered: (id)aSender +{ + if ( m_aCommand.isEmpty() ) + return; + + SolarMutexGuard aGuard; + + if ( m_aCommand == "vnd.org.libreoffice.recentdocs:ClearRecentFileList" ) + { + // Clearing the recent file list requires an extra step + SvtHistoryOptions::Clear( EHistoryType::PickList, false ); + } + else if ( m_aCommand == ".uno:Open" ) + { + ShutdownIcon::FileOpen(); + return; + } + else if ( m_aCommand == ".uno:ConfigureDialog" ) + { + // Selecting some menu items will cause a crash if there are + // no visibile windows + ShutdownIcon::OpenURL( STARTMODULE_URL, "_default" ); + } + else if ( m_aCommand == UNO_TOGGLECURRENTMODULE_COMMAND ) + { + bool bIsExclusive = officecfg::Office::Common::History::ShowCurrentModuleOnly::get(); + std::shared_ptr<comphelper::ConfigurationChanges> batch(comphelper::ConfigurationChanges::create()); + officecfg::Office::Common::History::ShowCurrentModuleOnly::set(!bIsExclusive, batch); + batch->commit(); + [self setState: bIsExclusive ? NSControlStateValueOff : NSControlStateValueOn]; + return; + } + + // "private:" commands are used for menu items in the File > New menu + if ( m_aCommand.startsWith( "private:" ) || m_aCommand == STARTMODULE_URL ) + ShutdownIcon::OpenURL( m_aCommand, "_default" ); + else + ShutdownIcon::FromCommand( m_aCommand ); +} + +-(void)setCommand: (OUString)aCommand +{ + m_aCommand = aCommand; +} + +@end + @interface RecentMenuDelegate : NSObject <NSMenuDelegate> { std::vector< RecentMenuEntry >* m_pRecentFilesItems; @@ -175,6 +244,8 @@ class RecentFilesStringLength : public ::cppu::WeakImplHelper< css::util::XStrin -(void)menuNeedsUpdate:(NSMenu *)menu { + SolarMutexGuard aGuard; + // clear menu int nItems = [menu numberOfItems]; while( nItems -- ) @@ -202,38 +273,114 @@ class RecentFilesStringLength : public ::cppu::WeakImplHelper< css::util::XStrin // insert new recent items for ( std::vector<RecentMenuEntry>::size_type i = 0; i < m_pRecentFilesItems->size(); i++ ) { + OUStringBuffer aMenuShortCut; + if ( i <= 9 ) + { + if ( i == 9 ) + aMenuShortCut.append( "1~0. " ); + else + { + aMenuShortCut.append( "~N. " ); + aMenuShortCut[ 1 ] = sal_Unicode( i + '1' ); + } + } + else + { + aMenuShortCut.append( OUString::number(sal_Int32( i + 1 ) ) + ". " ); + } + OUString aMenuTitle; INetURLObject aURL( (*m_pRecentFilesItems)[i].aURL ); + NSImage *pImage = nil; if ( aURL.GetProtocol() == INetProtocol::File ) { - // Do handle file URL differently => convert it to a system - // path and abbreviate it with a special function: - OUString aSystemPath( aURL.getFSysPath( FSysStyle::Detect ) ); - OUString aCompactedSystemPath; - - oslFileError nError = osl_abbreviateSystemPath( aSystemPath.pData, &aCompactedSystemPath.pData, 46, nullptr ); - if ( !nError ) - aMenuTitle = aCompactedSystemPath; - else - aMenuTitle = aSystemPath; + // Do handle file URL differently: don't show the protocol, + // just the file name + aMenuTitle = aURL.GetLastName(INetURLObject::DecodeMechanism::WithCharset); + + if ( [NSApp respondsToSelector: @selector(createNSImage:)] ) + { + BitmapEx aThumbnail(SvFileInformationManager::GetFileImageId(aURL)); + Size aBmpSize = aThumbnail.GetSizePixel(); + if ( aBmpSize.Width() > 0 && aBmpSize.Height() > 0 ) + { + Image aImage( aThumbnail ); + NSValue *pImageValue = [NSValue valueWithPointer: &aImage]; + pImage = [NSApp performSelector: @selector(createNSImage:) withObject: pImageValue]; + } + } } else { - // Use INetURLObject to abbreviate all other URLs - css::uno::Reference< css::util::XStringWidth > xStringLength( new RecentFilesStringLength() ); - aMenuTitle = aURL.getAbbreviated( xStringLength, 46, INetURLObject::DecodeMechanism::Unambiguous ); + // In all other URLs show the protocol name before the file name + aMenuTitle = INetURLObject::GetSchemeName(aURL.GetProtocol()) + ": " + aURL.getName(); } + aMenuShortCut.append( aMenuTitle ); + aMenuTitle = MnemonicGenerator::EraseAllMnemonicChars( aMenuShortCut.makeStringAndClear() ); + if ( aMenuTitle.isEmpty() ) + continue; + + if ( aMenuTitle.endsWith( "...", &aMenuTitle ) ) + aMenuTitle += u"\u2026"; + NSMenuItem* pNewItem = [[NSMenuItem alloc] initWithTitle: getAutoreleasedString( aMenuTitle ) action: @selector(executeRecentEntry:) keyEquivalent: @""]; [pNewItem setTag: i]; [pNewItem setTarget: self]; [pNewItem setEnabled: YES]; + if ( pImage ) + { + [pNewItem setImage: pImage]; + [pImage release]; + } [menu addItem: pNewItem]; [pNewItem autorelease]; } + + if ( [menu numberOfItems] ) + { + TranslateId aId( "STR_CLEAR_RECENT_FILES", "Clear List" ); + OUString aClearList = Translate::get( aId, Translate::Create("fwk") ); + if ( !aClearList.isEmpty() ) + { + [menu addItem: [NSMenuItem separatorItem]]; + + QSCommandMenuItem* pNewItem = [[QSCommandMenuItem alloc] initWithTitle: getAutoreleasedString( aClearList ) action: @selector(menuItemTriggered:) keyEquivalent: @""]; + [pNewItem setCommand: "vnd.org.libreoffice.recentdocs:ClearRecentFileList"]; + [pNewItem setTarget: pNewItem]; + [pNewItem setEnabled: YES]; + [menu addItem: pNewItem]; + [pNewItem autorelease]; + + aId = TranslateId( "STR_TOGGLECURRENTMODULE", "Current Module Only" ); + OUString aToggleCurrentMode = Translate::get( aId, Translate::Create("fwk") ); + if ( !aToggleCurrentMode.isEmpty() ) + { + pNewItem = [[QSCommandMenuItem alloc] initWithTitle: getAutoreleasedString( aToggleCurrentMode ) action: @selector(menuItemTriggered:) keyEquivalent: @""]; + [pNewItem setCommand: UNO_TOGGLECURRENTMODULE_COMMAND]; + [pNewItem setTarget: pNewItem]; + [pNewItem setState: officecfg::Office::Common::History::ShowCurrentModuleOnly::get() ? NSControlStateValueOn : NSControlStateValueOff]; + [pNewItem setEnabled: YES]; + [menu addItem: pNewItem]; + [pNewItem autorelease]; + } + } + } + else + { + TranslateId aId( "STR_NODOCUMENT", "No Documents" ); + OUString aNoDocuments = Translate::get( aId, Translate::Create("fwk") ); + if ( !aNoDocuments.isEmpty() ) + { + NSMenuItem* pNewItem = [[NSMenuItem alloc] initWithTitle: getAutoreleasedString( aNoDocuments ) action: nil keyEquivalent: @""]; + [pNewItem setEnabled: YES]; + [menu addItem: pNewItem]; + [pNewItem autorelease]; + } + } } -(void)executeRecentEntry: (NSMenuItem*)item @@ -311,6 +458,7 @@ static void appendMenuItem( NSMenu* i_pMenu, NSMenu* i_pDockMenu, const OUString [pItem setTarget: pExecute]; [pItem setEnabled: YES]; [i_pMenu addItem: pItem]; + [pItem autorelease]; if( i_pDockMenu ) { @@ -323,6 +471,7 @@ static void appendMenuItem( NSMenu* i_pMenu, NSMenu* i_pDockMenu, const OUString [pItem setTarget: pExecute]; [pItem setEnabled: YES]; [i_pDockMenu addItem: pItem]; + [pItem autorelease]; } } @@ -344,6 +493,206 @@ static void appendRecentMenu( NSMenu* i_pMenu, const OUString& i_rTitle ) [pItem setSubmenu: pRecentMenu]; } +void setKeyEquivalent( const vcl::KeyCode &rKeyCode, NSMenuItem *pNSMenuItem ) +{ + if ( !pNSMenuItem ) + return; + + sal_uInt16 nKeyCode = rKeyCode.GetCode(); + if ( !nKeyCode ) + return; + + sal_Unicode nCommandKey = 0; + if ((nKeyCode>=KEY_A) && (nKeyCode<=KEY_Z)) // letter A..Z + nCommandKey = nKeyCode - KEY_A + 'a'; + else if ((nKeyCode>=KEY_0) && (nKeyCode<=KEY_9)) // numbers 0..9 + nCommandKey = nKeyCode - KEY_0 + '0'; + else if ((nKeyCode>=KEY_F1) && (nKeyCode<=KEY_F26)) // function keys F1..F26 + nCommandKey = nKeyCode - KEY_F1 + NSF1FunctionKey; + + if ( !nCommandKey ) + return; + + sal_uInt16 nModifier = rKeyCode.GetModifier(); + int nItemModifier = 0; + + if ( nModifier & KEY_SHIFT ) + { + nItemModifier |= NSEventModifierFlagShift; // actually useful only for function keys + if ( nKeyCode >= KEY_A && nKeyCode <= KEY_Z ) + nCommandKey = nKeyCode - KEY_A + 'A'; + } + + if ( nModifier & KEY_MOD1 ) + nItemModifier |= NSEventModifierFlagCommand; + + if ( nModifier & KEY_MOD2 ) + nItemModifier |= NSEventModifierFlagOption; + + if ( nModifier & KEY_MOD3 ) + nItemModifier |= NSEventModifierFlagControl; + + OUString aCommandKey( &nCommandKey, 1 ); + NSString *pCommandKey = [NSString stringWithCharacters: reinterpret_cast< unichar const* >(aCommandKey.getStr()) length: aCommandKey.getLength()]; + [pNSMenuItem setKeyEquivalent: pCommandKey]; + [pNSMenuItem setKeyEquivalentModifierMask: nItemModifier]; +} + +static NSMenu *getNSMenuForVCLMenu( Menu *pMenu ) +{ + NSMenu *pRet = nil; + + if ( !pMenu ) + return pRet; + + pMenu->Activate(); + + sal_uInt16 nItemCount = pMenu->GetItemCount(); + if ( nItemCount ) + { + pRet = [[[NSMenu alloc] initWithTitle: @""] autorelease]; + [pRet setAutoenablesItems: NO]; + for ( sal_uInt16 i = 0; i < nItemCount; i++ ) + { + sal_uInt16 nId = pMenu->GetItemId( i ); + if ( nId && pMenu->IsItemEnabled( nId ) ) + { + OUString aText = MnemonicGenerator::EraseAllMnemonicChars( pMenu->GetItemText( nId ) ); + if ( aText.isEmpty() ) + continue; + + if ( aText.endsWith( "...", &aText ) ) + aText += u"\u2026"; + + // Use a custom menu in place of the Start Center's recent + // documents menu so that the list can be dynamically updated + OUString aCommand = pMenu->GetItemCommand( nId ); + if ( aCommand == ".uno:RecentFileList" ) + { + appendRecentMenu( pRet, aText ); + continue; + } + + NSString *pText = getAutoreleasedString( aText ); + // TODO: use the QSMenuExecute class to connect the command + // string to one of the existing handler functions + QSCommandMenuItem *pNSMenuItem = [[QSCommandMenuItem alloc] initWithTitle: pText action: @selector(menuItemTriggered:) keyEquivalent: @""]; + NSMenu *pNSSubmenu = getNSMenuForVCLMenu( pMenu->GetPopupMenu( nId ) ); + if ( pNSSubmenu && [pNSSubmenu numberOfItems] ) + { + [pNSSubmenu setTitle: pText]; + [pNSMenuItem setSubmenu: pNSSubmenu]; + + if ( aCommand == ".uno:AddDirect" ) + { + SvtModuleOptions aModuleOptions; + if ( aModuleOptions.IsModuleInstalled( SvtModuleOptions::EModule::STARTMODULE ) ) + { + QSCommandMenuItem *pStartModuleMenuItem = [[QSCommandMenuItem alloc] initWithTitle: getAutoreleasedString( SfxResId( STR_QUICKSTART_STARTCENTER ) ) action: @selector(menuItemTriggered:) keyEquivalent: @"n"]; + [pStartModuleMenuItem setTarget: pStartModuleMenuItem]; + [pStartModuleMenuItem setCommand: STARTMODULE_URL]; + [pNSSubmenu insertItem: pStartModuleMenuItem atIndex: 0]; + [pStartModuleMenuItem autorelease]; + } + } + } + else if ( !aCommand.isEmpty() ) + { + [pNSMenuItem setTarget: pNSMenuItem]; + [pNSMenuItem setCommand: aCommand]; + + // Use the default menu's special "open new file" shortcuts + if ( aCommand == WRITER_URL ) + [pNSMenuItem setKeyEquivalent: @"t"]; + else if ( aCommand == CALC_URL ) + [pNSMenuItem setKeyEquivalent: @"s"]; + else if ( aCommand == IMPRESS_WIZARD_URL ) + [pNSMenuItem setKeyEquivalent: @"p"]; + else if ( aCommand == DRAW_URL ) + [pNSMenuItem setKeyEquivalent: @"d"]; + else if ( aCommand == MATH_URL ) + [pNSMenuItem setKeyEquivalent: @"f"]; + else if ( aCommand == BASE_URL ) + [pNSMenuItem setKeyEquivalent: @"a"]; + else + setKeyEquivalent( pMenu->GetAccelKey( nId ), pNSMenuItem ); + } + + [pRet addItem: pNSMenuItem]; + [pNSMenuItem autorelease]; + } + else if ( pMenu->GetItemType( i ) == MenuItemType::SEPARATOR ) + { + [pRet addItem: [NSMenuItem separatorItem]]; + } + } + } + + pMenu->Deactivate(); + + return pRet; +} + +static void clearDefaultMenuBar() +{ + if( ![NSApp respondsToSelector: @selector(removeFallbackMenuItem:)] ) + return; + + // Remove previous default menu + if ( pDefMenu ) + [NSApp performSelector:@selector(removeFallbackMenuItem:) withObject: pDefMenu]; + + // Remove previous preferred menu + if ( pPreferredMenus && [pPreferredMenus count] ) + { + for ( NSMenuItem *pNSMenuItem in pPreferredMenus ) + [NSApp performSelector:@selector(removeFallbackMenuItem:) withObject: pNSMenuItem]; + } +} + +static void resetMenuBar() +{ + if( ![NSApp respondsToSelector: @selector(addFallbackMenuItem:)] ) + return; + + clearDefaultMenuBar(); + + if ( pPreferredMenus && [pPreferredMenus count] ) + { + for ( NSMenuItem *pNSMenuItem in pPreferredMenus ) + [NSApp performSelector:@selector(addFallbackMenuItem:) withObject: pNSMenuItem]; + } + else if ( pDefMenu ) + { + [NSApp performSelector:@selector(addFallbackMenuItem:) withObject: pDefMenu]; + } +} + +void ShutdownIcon::SetDefaultMenuBar( MenuBar *pMenuBar ) +{ + if ( !pMenuBar ) + return; + + SolarMutexGuard aGuard; + + clearDefaultMenuBar(); + if ( pPreferredMenus ) + { + [pPreferredMenus release]; + pPreferredMenus = nil; + } + + NSMenu *pNSMenu = getNSMenuForVCLMenu( pMenuBar ); + if ( pNSMenu && [pNSMenu numberOfItems] ) + { + pPreferredMenus = [NSMutableArray arrayWithArray: [pNSMenu itemArray]]; + [pNSMenu removeAllItems]; + [pPreferredMenus retain]; + } + + resetMenuBar(); +} + extern "C" { @@ -444,7 +793,7 @@ void aqua_init_systray() appendMenuItem( pMenu, pDockMenu, aTitle, MI_OPEN, aKeyEquiv ); [pDefMenu setSubmenu: pMenu]; - [NSApp performSelector:@selector(addFallbackMenuItem:) withObject: pDefMenu]; + resetMenuBar(); if( [NSApp respondsToSelector: @selector(addDockMenuItem:)] ) { @@ -454,6 +803,9 @@ void aqua_init_systray() } else OSL_FAIL( "addDockMenuItem selector failed on NSApp" ); + + [pMenu autorelease]; + [pDockMenu autorelease]; } else OSL_FAIL( "addFallbackMenuItem selector failed on NSApp" ); diff --git a/sfx2/source/appl/shutdowniconw32.cxx b/sfx2/source/appl/shutdowniconw32.cxx index 5d4c89307baf..409ba80bbf2c 100644 --- a/sfx2/source/appl/shutdowniconw32.cxx +++ b/sfx2/source/appl/shutdowniconw32.cxx @@ -25,7 +25,7 @@ #undef WB_LEFT #undef WB_RIGHT -#include "shutdownicon.hxx" +#include <shutdownicon.hxx> #include <sfx2/sfxresid.hxx> #include <sfx2/strings.hrc> #include <shlobj.h> diff --git a/sfx2/source/dialog/backingcomp.cxx b/sfx2/source/dialog/backingcomp.cxx index 668b4e00934f..2992cb3890e5 100644 --- a/sfx2/source/dialog/backingcomp.cxx +++ b/sfx2/source/dialog/backingcomp.cxx @@ -45,6 +45,10 @@ #include <sfx2/notebookbar/SfxNotebookBar.hxx> +#ifdef MACOSX +#include <shutdownicon.hxx> +#endif + namespace { /** @@ -396,6 +400,12 @@ void SAL_CALL BackingComp::attachFrame( /*IN*/ const css::uno::Reference< css::f pBack->get_width_request(), pBack->get_height_request() + nMenuHeight)); +#ifdef MACOSX + SystemWindow *pSysWin = static_cast<SystemWindow*>(pParent.get()); + if (pSysWin) + ShutdownIcon::SetDefaultMenuBar(pSysWin->GetMenuBar()); +#endif + /* } SAFE */ } diff --git a/sfx2/source/appl/shutdownicon.hxx b/sfx2/source/inc/shutdownicon.hxx similarity index 96% rename from sfx2/source/appl/shutdownicon.hxx rename to sfx2/source/inc/shutdownicon.hxx index 535a24b4dff4..1127a9ca352c 100644 --- a/sfx2/source/appl/shutdownicon.hxx +++ b/sfx2/source/inc/shutdownicon.hxx @@ -32,6 +32,10 @@ #include <tools/link.hxx> #include <memory> +#ifdef MACOSX +#include <vcl/menu.hxx> +#endif + extern "C" { void SAL_DLLPUBLIC_EXPORT plugin_init_sys_tray(); @@ -101,6 +105,7 @@ class ShutdownIcon : public ShutdownIconServiceBase static void OpenURL( const OUString& aURL, const OUString& rTarget, const css::uno::Sequence< css::beans::PropertyValue >& = css::uno::Sequence< css::beans::PropertyValue >( 0 ) ); static void FromTemplate(); + static void FromCommand( const OUString& rCommand ); static void SetAutostart( bool bActivate ); static bool GetAutostart(); @@ -139,6 +144,8 @@ class ShutdownIcon : public ShutdownIconServiceBase #ifdef _WIN32 static void EnableAutostartW32( const OUString &aShortcutName ); static OUString GetAutostartFolderNameW32(); +#elif defined MACOSX + static void SetDefaultMenuBar( MenuBar *pMenuBar ); #endif }; diff --git a/solenv/clang-format/excludelist b/solenv/clang-format/excludelist index 6811156c08ec..44790f0c3e64 100644 --- a/solenv/clang-format/excludelist +++ b/solenv/clang-format/excludelist @@ -10187,7 +10187,6 @@ sfx2/source/appl/preventduplicateinteraction.cxx sfx2/source/appl/sfxhelp.cxx sfx2/source/appl/sfxpicklist.cxx sfx2/source/appl/shutdownicon.cxx -sfx2/source/appl/shutdownicon.hxx sfx2/source/appl/shutdowniconw32.cxx sfx2/source/appl/workwin.cxx sfx2/source/appl/xpackcreator.cxx @@ -10309,6 +10308,7 @@ sfx2/source/inc/objshimp.hxx sfx2/source/inc/partwnd.hxx sfx2/source/inc/recfloat.hxx sfx2/source/inc/sfxurlrelocator.hxx +sfx2/source/inc/shutdownicon.hxx sfx2/source/inc/slotserv.hxx sfx2/source/inc/splitwin.hxx sfx2/source/inc/statcach.hxx diff --git a/vcl/inc/osx/vclnsapp.h b/vcl/inc/osx/vclnsapp.h index 21a71a01d23e..9855a9cc3c5c 100644 --- a/vcl/inc/osx/vclnsapp.h +++ b/vcl/inc/osx/vclnsapp.h @@ -64,6 +64,7 @@ class AquaSalFrame; -(BOOL)applicationShouldHandleReopen: (NSApplication*)pApp hasVisibleWindows: (BOOL)bWinVisible; -(BOOL)applicationSupportsSecureRestorableState: (NSApplication *)pApp; -(void)setDockIconClickHandler: (NSObject*)pHandler; +-(NSImage*)createNSImage: (NSValue*)pImageValue; @end /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/osx/vclnsapp.mm b/vcl/osx/vclnsapp.mm index 065e1c95810b..19c90cbb323e 100644 --- a/vcl/osx/vclnsapp.mm +++ b/vcl/osx/vclnsapp.mm @@ -478,6 +478,17 @@ GetSalData()->mpDockIconClickHandler = pHandler; } +-(NSImage*)createNSImage: (NSValue*)pImageValue +{ + if (pImageValue) + { + Image *pImage = static_cast<Image*>([pImageValue pointerValue]); + if (pImage) + return CreateNSImage(*pImage); + } + + return nil; +} @end