From 0ff1bdec09e87d58fd7ffcbb1da50531aeb0061a Mon Sep 17 00:00:00 2001 From: Tobias Taschner Date: Thu, 18 Mar 2021 22:12:14 +0100 Subject: [PATCH] Add wxFullScreenEvent for macOS Send a wxFullScreenEvent when the user enters or exits full screen on macOS. EnableFullScreenView() has to be used to enable the native full screen API. Closes https://github.com/wxWidgets/wxWidgets/pull/2284 --- include/wx/event.h | 26 +++++++++++++++++++++ include/wx/osx/cocoa/private.h | 2 ++ interface/wx/event.h | 41 +++++++++++++++++++++++++++++++++- interface/wx/toplevel.h | 18 +++++++-------- src/common/event.cpp | 2 ++ src/osx/cocoa/nonownedwnd.mm | 27 ++++++++++++++++++++++ 6 files changed, 106 insertions(+), 10 deletions(-) diff --git a/include/wx/event.h b/include/wx/event.h index f71c271345..c14b5def97 100644 --- a/include/wx/event.h +++ b/include/wx/event.h @@ -681,6 +681,7 @@ class WXDLLIMPEXP_FWD_CORE wxWindowDestroyEvent; class WXDLLIMPEXP_FWD_CORE wxShowEvent; class WXDLLIMPEXP_FWD_CORE wxIconizeEvent; class WXDLLIMPEXP_FWD_CORE wxMaximizeEvent; +class WXDLLIMPEXP_FWD_CORE wxFullScreenEvent; class WXDLLIMPEXP_FWD_CORE wxMouseCaptureChangedEvent; class WXDLLIMPEXP_FWD_CORE wxMouseCaptureLostEvent; class WXDLLIMPEXP_FWD_CORE wxPaintEvent; @@ -832,6 +833,7 @@ wxDECLARE_EXPORTED_EVENT(WXDLLIMPEXP_CORE, wxEVT_DESTROY, wxWindowDestroyEvent); wxDECLARE_EXPORTED_EVENT(WXDLLIMPEXP_CORE, wxEVT_SHOW, wxShowEvent); wxDECLARE_EXPORTED_EVENT(WXDLLIMPEXP_CORE, wxEVT_ICONIZE, wxIconizeEvent); wxDECLARE_EXPORTED_EVENT(WXDLLIMPEXP_CORE, wxEVT_MAXIMIZE, wxMaximizeEvent); +wxDECLARE_EXPORTED_EVENT(WXDLLIMPEXP_CORE, wxEVT_FULLSCREEN, wxFullScreenEvent); wxDECLARE_EXPORTED_EVENT(WXDLLIMPEXP_CORE, wxEVT_MOUSE_CAPTURE_CHANGED, wxMouseCaptureChangedEvent); wxDECLARE_EXPORTED_EVENT(WXDLLIMPEXP_CORE, wxEVT_MOUSE_CAPTURE_LOST, wxMouseCaptureLostEvent); wxDECLARE_EXPORTED_EVENT(WXDLLIMPEXP_CORE, wxEVT_PAINT, wxPaintEvent); @@ -2725,6 +2727,30 @@ private: wxDECLARE_DYNAMIC_CLASS_NO_ASSIGN(wxMaximizeEvent); }; +/* + wxEVT_FULLSCREEN + */ +class WXDLLIMPEXP_CORE wxFullScreenEvent : public wxEvent +{ +public: + wxFullScreenEvent(int winid = 0, bool fullscreen = true) + : wxEvent(winid, wxEVT_FULLSCREEN) + { m_fullscreen = fullscreen; } + wxFullScreenEvent(const wxFullScreenEvent& event) + : wxEvent(event) + { m_fullscreen = event.m_fullscreen; } + + bool IsFullScreen() const { return m_fullscreen; } + + virtual wxEvent *Clone() const wxOVERRIDE { return new wxFullScreenEvent(*this); } + +protected: + bool m_fullscreen; + +private: + wxDECLARE_DYNAMIC_CLASS_NO_ASSIGN(wxFullScreenEvent); +}; + // Joystick event class /* wxEVT_JOY_BUTTON_DOWN, diff --git a/include/wx/osx/cocoa/private.h b/include/wx/osx/cocoa/private.h index c145871fc6..c59c8bb231 100644 --- a/include/wx/osx/cocoa/private.h +++ b/include/wx/osx/cocoa/private.h @@ -341,6 +341,8 @@ public : CGWindowLevel GetWindowLevel() const wxOVERRIDE { return m_macWindowLevel; } void RestoreWindowLevel() wxOVERRIDE; + bool m_macIgnoreNextFullscreenChange = false; + static WX_NSResponder GetNextFirstResponder() ; static WX_NSResponder GetFormerFirstResponder() ; protected : diff --git a/interface/wx/event.h b/interface/wx/event.h index 1c48ef361a..42c7c700fa 100644 --- a/interface/wx/event.h +++ b/interface/wx/event.h @@ -2262,6 +2262,46 @@ public: wxMaximizeEvent(int id = 0); }; +/** + @class wxFullScreenEvent + + An event being sent when the user enters or exits full screen mode. + + Currently this event is only generated in the wxOSX/Cocoa port when + wxTopLevelWindow::EnableFullScreenView() is enabled and the user + the user enters or exits full screen. Note that this event is @e not + generated when wxTopLevelWindow::ShowFullScreen(). + + @beginEventTable{wxFullScreenEvent} + @event{EVT_FULLSCREEN(func)} + Process a @c wxEVT_FULLSCREEN event. + @endEventTable + + @library{wxcore} + @category{events} + + @since 3.1.5 + + @see @ref overview_events, wxTopLevelWindow::EnableFullScreenView, + wxTopLevelWindow::IsFullScreen +*/ +class wxFullScreenEvent : public wxEvent +{ +public: + /** + Constructor. + */ + wxFullScreenEvent(int id = 0, bool fullscreen = true); + + /** + Returns @true if the frame entered full screen, @false if exited + full screen. + */ + bool IsFullScreen() const; +}; + + + /** The possibles modes to pass to wxUpdateUIEvent::SetMode(). */ @@ -5151,4 +5191,3 @@ wxEventType wxEVT_WINDOW_MODAL_DIALOG_CLOSED; #endif // wxUSE_GUI //@} - diff --git a/interface/wx/toplevel.h b/interface/wx/toplevel.h index 18d3c6c374..ab852628f3 100644 --- a/interface/wx/toplevel.h +++ b/interface/wx/toplevel.h @@ -68,6 +68,8 @@ enum See wxMoveEvent. @event{EVT_SHOW(func)} Process a @c wxEVT_SHOW event. See wxShowEvent. + @event{EVT_FULLSCREEN(id, func)} + Process a @c wxEVT_FULLSCREEN event. See wxFullScreenEvent. @endEventTable @library{wxcore} @@ -632,17 +634,16 @@ public: virtual void ShowWithoutActivating(); /** - Enables the maximize button to toggle full screen mode. Prior to - macOS 10.10 a full screen button is added to the right upper corner - of a window's title bar. + Enables the zoom button to toggle full screen mode. - Currently only available for wxOSX/Cocoa. + A wxFullScreenEvent is generated when the users enters or exits + full screen via the enter/exit full screen button. @param enable - If @true (default) adds the full screen button in the title bar; - if @false the button is removed. + If @true (default) make the zoom button toggle full screen; + if @false the button does only toggle zoom. - @return @true if the button was added or removed, @false if running + @return @true if the button behaviour has been changed, @false if running under another OS. @note Having the button is also required to let ShowFullScreen() @@ -653,7 +654,7 @@ public: @onlyfor{wxosx} - @see ShowFullScreen() + @see ShowFullScreen(), wxFullScreenEvent @since 3.1.0 */ @@ -718,4 +719,3 @@ public: */ void UseNativeDecorationsByDefault(bool native = true); }; - diff --git a/src/common/event.cpp b/src/common/event.cpp index f8a26277e5..a2c64b72a0 100644 --- a/src/common/event.cpp +++ b/src/common/event.cpp @@ -80,6 +80,7 @@ wxIMPLEMENT_DYNAMIC_CLASS(wxShowEvent, wxEvent); wxIMPLEMENT_DYNAMIC_CLASS(wxMaximizeEvent, wxEvent); wxIMPLEMENT_DYNAMIC_CLASS(wxIconizeEvent, wxEvent); + wxIMPLEMENT_DYNAMIC_CLASS(wxFullScreenEvent, wxEvent); wxIMPLEMENT_DYNAMIC_CLASS(wxMenuEvent, wxEvent); wxIMPLEMENT_DYNAMIC_CLASS(wxJoystickEvent, wxEvent); wxIMPLEMENT_DYNAMIC_CLASS(wxDropFilesEvent, wxEvent); @@ -288,6 +289,7 @@ wxDEFINE_EVENT( wxEVT_DESTROY, wxWindowDestroyEvent ); wxDEFINE_EVENT( wxEVT_SHOW, wxShowEvent ); wxDEFINE_EVENT( wxEVT_ICONIZE, wxIconizeEvent ); wxDEFINE_EVENT( wxEVT_MAXIMIZE, wxMaximizeEvent ); +wxDEFINE_EVENT( wxEVT_FULLSCREEN, wxFullScreenEvent ); wxDEFINE_EVENT( wxEVT_MOUSE_CAPTURE_CHANGED, wxMouseCaptureChangedEvent ); wxDEFINE_EVENT( wxEVT_MOUSE_CAPTURE_LOST, wxMouseCaptureLostEvent ); wxDEFINE_EVENT( wxEVT_PAINT, wxPaintEvent ); diff --git a/src/osx/cocoa/nonownedwnd.mm b/src/osx/cocoa/nonownedwnd.mm index 35c86fcf3b..dd98b3db85 100644 --- a/src/osx/cocoa/nonownedwnd.mm +++ b/src/osx/cocoa/nonownedwnd.mm @@ -606,6 +606,25 @@ extern int wxOSXGetIdFromSelector(SEL action ); return true; } +static void SendFullScreenWindowEvent(NSNotification* notification, bool fullscreen) +{ + NSWindow* window = (NSWindow*) [notification object]; + wxNonOwnedWindowCocoaImpl* windowimpl = [window WX_implementation]; + if ( windowimpl ) + { + if (windowimpl->m_macIgnoreNextFullscreenChange) + { + windowimpl->m_macIgnoreNextFullscreenChange = false; + return; + } + + wxNonOwnedWindow* wxpeer = windowimpl->GetWXPeer(); + wxFullScreenEvent event(wxpeer->GetId(), fullscreen); + event.SetEventObject(wxpeer); + wxpeer->HandleWindowEvent(event); + } +} + // work around OS X bug, on a secondary monitor an already fully sized window // (eg maximized) will not be correctly put to full screen size and keeps a 22px // title band at the top free, therefore we force the correct content size @@ -624,6 +643,13 @@ extern int wxOSXGetIdFromSelector(SEL action ); { [view setFrameSize: expectedframerect.size]; } + + SendFullScreenWindowEvent(notification, true); +} + +- (void)windowWillExitFullScreen:(NSNotification *)notification +{ + SendFullScreenWindowEvent(notification, false); } // from https://developer.apple.com/library/archive/documentation/GraphicsAnimation/Conceptual/HighResolutionOSX/CapturingScreenContents/CapturingScreenContents.html @@ -1178,6 +1204,7 @@ bool wxNonOwnedWindowCocoaImpl::ShowFullScreen(bool show, long WXUNUSED(style)) { if ( show != IsFullScreen() ) { + m_macIgnoreNextFullscreenChange = true; [m_macWindow toggleFullScreen: nil]; }