From fe60c9af6a55cbb919f35a2a66d1d5054aa1d6cc Mon Sep 17 00:00:00 2001 From: livecodepanos Date: Tue, 20 Oct 2020 15:31:42 +0300 Subject: [PATCH] [[ Bug 22829 ]] Make 'working screenrect' return the safe area on iOS --- engine/src/desktop-dc.cpp | 2 +- engine/src/desktop-dc.h | 2 +- engine/src/em-dc.cpp | 2 +- engine/src/em-dc.h | 2 +- engine/src/exec-interface2.cpp | 2 +- engine/src/lnxdc.cpp | 2 +- engine/src/lnxdc.h | 2 +- engine/src/mblandroiddc.cpp | 2 +- engine/src/mbldc.h | 2 +- engine/src/mbliphoneapp.h | 1 + engine/src/mbliphoneapp.mm | 39 ++++++++++++++++++++++++++-------- engine/src/mbliphonedc.mm | 8 ++++--- engine/src/uidc.cpp | 8 +++---- engine/src/uidc.h | 4 ++-- engine/src/w32dc.h | 2 +- engine/src/w32dce.cpp | 2 +- 16 files changed, 53 insertions(+), 29 deletions(-) diff --git a/engine/src/desktop-dc.cpp b/engine/src/desktop-dc.cpp index 77f8b256c2c..815b067439a 100644 --- a/engine/src/desktop-dc.cpp +++ b/engine/src/desktop-dc.cpp @@ -212,7 +212,7 @@ uint16_t MCScreenDC::platform_getheight(void) return t_viewport . height; } -bool MCScreenDC::platform_getdisplays(bool p_effective, MCDisplay *& r_displays, uint32_t &r_count) +bool MCScreenDC::platform_getdisplays(bool p_effective, MCDisplay *& r_displays, uint32_t &r_count, Boolean p_safe_area) { bool t_success; t_success = true; diff --git a/engine/src/desktop-dc.h b/engine/src/desktop-dc.h index 0743af1ab32..3ef60e001ba 100644 --- a/engine/src/desktop-dc.h +++ b/engine/src/desktop-dc.h @@ -55,7 +55,7 @@ class MCScreenDC: public MCUIDC virtual uint16_t platform_getwidth(void); virtual uint16_t platform_getheight(void); - virtual bool platform_getdisplays(bool p_effective, MCDisplay *&r_displays, uint32_t &r_count); + virtual bool platform_getdisplays(bool p_effective, MCDisplay *&r_displays, uint32_t &r_count, Boolean p_safe_area = false); virtual void platform_boundrect(MCRectangle &rect, Boolean title, Window_mode m, Boolean resizable); virtual void resetcursors(); diff --git a/engine/src/em-dc.cpp b/engine/src/em-dc.cpp index 8d45a99602c..454cef4bb56 100644 --- a/engine/src/em-dc.cpp +++ b/engine/src/em-dc.cpp @@ -251,7 +251,7 @@ MCScreenDC::platform_getwindowgeometry(Window p_window, * Display management * ================================================================ */ -bool MCScreenDC::platform_getdisplays(bool p_effective, MCDisplay *&r_displays, uint32_t &r_count) +bool MCScreenDC::platform_getdisplays(bool p_effective, MCDisplay *&r_displays, uint32_t &r_count, Boolean p_safe_area) { MCDisplay *t_display = nil; if (!MCMemoryNew(t_display)) diff --git a/engine/src/em-dc.h b/engine/src/em-dc.h index 46372eab457..8677b25a0b5 100644 --- a/engine/src/em-dc.h +++ b/engine/src/em-dc.h @@ -80,7 +80,7 @@ class MCScreenDC: public MCUIDC /* ---------- Display management */ - virtual bool platform_getdisplays(bool p_effective, MCDisplay *&r_displays, uint32_t &r_count); + virtual bool platform_getdisplays(bool p_effective, MCDisplay *&r_displays, uint32_t &r_count, Boolean p_safe_area = false); /* ---------- Event loop */ virtual Boolean wait(real64_t p_duration, diff --git a/engine/src/exec-interface2.cpp b/engine/src/exec-interface2.cpp index 63164d7d345..8faa01ff1a3 100644 --- a/engine/src/exec-interface2.cpp +++ b/engine/src/exec-interface2.cpp @@ -1933,7 +1933,7 @@ void MCInterfaceSetTool(MCExecContext& ctxt, MCStringRef p_value) void MCInterfaceGetScreenRect(MCExecContext& ctxt, bool p_working, bool p_effective, MCRectangle& r_value) { const MCDisplay *t_displays; - MCscreen -> getdisplays(t_displays, p_effective); + MCscreen -> getdisplays(t_displays, p_effective, true); if (t_displays) { diff --git a/engine/src/lnxdc.cpp b/engine/src/lnxdc.cpp index 0bb8bee08b9..af95e39593f 100644 --- a/engine/src/lnxdc.cpp +++ b/engine/src/lnxdc.cpp @@ -307,7 +307,7 @@ bool MCScreenDC::apply_partial_struts(MCDisplay *p_displays, uint32_t p_display_ } // IM-2014-01-29: [[ HiDPI ]] Placeholder method for Linux HiDPI support -bool MCScreenDC::platform_getdisplays(bool p_effective, MCDisplay *&r_displays, uint32_t &r_display_count) +bool MCScreenDC::platform_getdisplays(bool p_effective, MCDisplay *&r_displays, uint32_t &r_display_count, Boolean p_safe_area) { return device_getdisplays(p_effective, r_displays, r_display_count); } diff --git a/engine/src/lnxdc.h b/engine/src/lnxdc.h index 047eef3807c..2ba3eb86f9c 100644 --- a/engine/src/lnxdc.h +++ b/engine/src/lnxdc.h @@ -250,7 +250,7 @@ class MCScreenDC : public MCUIDC // IM-2014-01-29: [[ HiDPI ]] Update device_* methods to platform-specific logical coord based methods virtual uint16_t platform_getwidth(void); virtual uint16_t platform_getheight(void); - virtual bool platform_getdisplays(bool p_effective, MCDisplay *&r_displays, uint32_t &r_count); + virtual bool platform_getdisplays(bool p_effective, MCDisplay *&r_displays, uint32_t &r_count, Boolean p_safe_area = false); virtual bool platform_getwindowgeometry(Window w, MCRectangle &drect); virtual void platform_boundrect(MCRectangle &rect, Boolean title, Window_mode m, Boolean resizable); virtual void platform_querymouse(int16_t &r_x, int16_t &r_y); diff --git a/engine/src/mblandroiddc.cpp b/engine/src/mblandroiddc.cpp index de53dfbb401..a3afca5e181 100644 --- a/engine/src/mblandroiddc.cpp +++ b/engine/src/mblandroiddc.cpp @@ -344,7 +344,7 @@ Window MCScreenDC::getroot() } // IM-2014-01-31: [[ HiDPI ]] Refactor to return display rects in logical coords and include pixel scale -bool MCScreenDC::platform_getdisplays(bool p_effective, MCDisplay *&r_displays, uint32_t &r_count) +bool MCScreenDC::platform_getdisplays(bool p_effective, MCDisplay *&r_displays, uint32_t &r_count, Boolean p_safe_area) { bool t_success; t_success = true; diff --git a/engine/src/mbldc.h b/engine/src/mbldc.h index c6d81aa9e70..d79d39c8e54 100644 --- a/engine/src/mbldc.h +++ b/engine/src/mbldc.h @@ -74,7 +74,7 @@ class MCScreenDC: public MCUIDC virtual uint16_t platform_getwidth(void); virtual uint16_t platform_getheight(void); - virtual bool platform_getdisplays(bool p_effective, MCDisplay *&r_displays, uint32_t &r_count); + virtual bool platform_getdisplays(bool p_effective, MCDisplay *&r_displays, uint32_t &r_count, Boolean p_safe_area = false); virtual bool platform_displayinfocacheable(void); virtual bool platform_getwindowgeometry(Window w, MCRectangle &drect); virtual void platform_boundrect(MCRectangle &rect, Boolean title, Window_mode m, Boolean resizable); diff --git a/engine/src/mbliphoneapp.h b/engine/src/mbliphoneapp.h index c4e949b1e67..eb94180aa88 100644 --- a/engine/src/mbliphoneapp.h +++ b/engine/src/mbliphoneapp.h @@ -389,6 +389,7 @@ UIView *MCIPhoneGetView(void); UIView *MCIPhoneGetRootView(void); UIView *MCIPhoneGetDisplayView(void); CGRect MCIPhoneGetViewBounds(void); +CGRect MCIPhoneGetWorkAreaBounds(void); CGRect MCIPhoneGetScreenBounds(void); void MCIPhoneActivateKeyboard(void); void MCIPhoneDeactivateKeyboard(void); diff --git a/engine/src/mbliphoneapp.mm b/engine/src/mbliphoneapp.mm index 21f0ed08425..19591065efa 100644 --- a/engine/src/mbliphoneapp.mm +++ b/engine/src/mbliphoneapp.mm @@ -957,13 +957,33 @@ - (CGRect)fetchScreenBounds CGRect t_viewport; t_viewport = [[UIScreen mainScreen] bounds]; - // MW-2014-10-02: [[ iOS 8 Support ]] iOS 8 already takes into account orientation when returning the bounds. - if (MCmajorosversion < 800 && UIInterfaceOrientationIsLandscape([self fetchOrientation])) - return CGRectMake(0.0f, 0.0f, t_viewport . size . height, t_viewport . size . width); - return t_viewport; } +- (CGRect)fetchWorkAreaBounds +{ +#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000 + if (@available(iOS 11.0, *)) + { + CGRect t_viewport; + t_viewport = [[UIScreen mainScreen] bounds]; + + UIWindow *t_window = [[UIApplication sharedApplication] windows][0]; + CGFloat t_top_padding = t_window.safeAreaInsets.top; + CGFloat t_bottom_padding = t_window.safeAreaInsets.bottom; + + CGFloat t_status_bar_size; + if (m_status_bar_hidden || (MCmajorosversion >= 700 && !m_status_bar_solid)|| ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone && m_status_bar_style == UIStatusBarStyleBlackTranslucent)) + t_status_bar_size = 0.0f; + else + t_status_bar_size = 20.0f; + + return CGRectMake(0.0f, t_top_padding + t_status_bar_size, t_viewport . size . width, t_viewport . size . height - t_top_padding - t_bottom_padding - t_status_bar_size); + } +#endif + return self.fetchViewBounds; +} + - (CGRect)fetchViewBounds { CGRect t_viewport; @@ -978,11 +998,7 @@ - (CGRect)fetchViewBounds t_status_bar_size = 0.0f; else t_status_bar_size = 20.0f; - - // MM-2014-09-26: [[ iOS 8 Support ]] iOS 8 already takes into account orientation when returning the bounds. - if (MCmajorosversion < 800 && UIInterfaceOrientationIsLandscape([self fetchOrientation])) - return CGRectMake(0.0f, t_status_bar_size, t_viewport . size . height, t_viewport . size . width - t_status_bar_size); - + return CGRectMake(0.0f, t_status_bar_size, t_viewport . size . width, t_viewport . size . height - t_status_bar_size); } @@ -1864,6 +1880,11 @@ CGRect MCIPhoneGetViewBounds(void) return [[MCIPhoneApplication sharedApplication] fetchViewBounds]; } +CGRect MCIPhoneGetWorkAreaBounds(void) +{ + return [[MCIPhoneApplication sharedApplication] fetchWorkAreaBounds]; +} + CGRect MCIPhoneGetScreenBounds(void) { return [[MCIPhoneApplication sharedApplication] fetchScreenBounds]; diff --git a/engine/src/mbliphonedc.mm b/engine/src/mbliphonedc.mm index eda623adf34..e0bdc17c05d 100644 --- a/engine/src/mbliphonedc.mm +++ b/engine/src/mbliphonedc.mm @@ -308,7 +308,7 @@ bool MCIPhoneIsOnScriptFiber(void) } // IM-2014-01-30: [[ HiDPI ]] Refactor to return in logical coordinates, with addition of screen pixel scale -bool MCScreenDC::platform_getdisplays(bool p_effective, MCDisplay *&r_displays, uint32_t &r_count) +bool MCScreenDC::platform_getdisplays(bool p_effective, MCDisplay *&r_displays, uint32_t &r_count, Boolean p_safe_area) { bool t_success; t_success = true; @@ -329,7 +329,10 @@ bool MCIPhoneIsOnScriptFiber(void) t_displays[0].pixel_scale = MCIPhoneGetDeviceScale(); t_displays[0].viewport = MCRectangleFromCGRect(MCIPhoneGetScreenBounds()); - t_displays[0].workarea = MCRectangleFromCGRect(MCIPhoneGetViewBounds()); + if (p_safe_area) + t_displays[0].workarea = MCRectangleFromCGRect(MCIPhoneGetWorkAreaBounds()); + else + t_displays[0].workarea = MCRectangleFromCGRect(MCIPhoneGetViewBounds()); if (p_effective) t_displays[0].workarea.height -= s_current_keyboard_height; @@ -345,7 +348,6 @@ bool MCIPhoneIsOnScriptFiber(void) } else MCMemoryDeleteArray(t_displays); - return t_success; } diff --git a/engine/src/uidc.cpp b/engine/src/uidc.cpp index 2e004601839..50bcd9e62df 100644 --- a/engine/src/uidc.cpp +++ b/engine/src/uidc.cpp @@ -537,14 +537,14 @@ bool MCUIDC::s_display_info_effective = false; // IM-2014-01-24: [[ HiDPI ]] Refactor to implement caching of display info in MCUIDC instead of subclasses // IM-2014-01-24: [[ HiDPI ]] Change to use logical coordinates - device coordinate conversion no longer needed -uint4 MCUIDC::getdisplays(const MCDisplay *&r_displays, bool p_effective) +uint4 MCUIDC::getdisplays(const MCDisplay *&r_displays, bool p_effective, bool p_safe_area) { if (p_effective != s_display_info_effective || !platform_displayinfocacheable()) cleardisplayinfocache(); - if (s_displays == nil) + if (s_displays == nil || p_safe_area) { - /* UNCHECKED */ platform_getdisplays(p_effective, s_displays, s_display_count); + /* UNCHECKED */ platform_getdisplays(p_effective, s_displays, s_display_count, p_safe_area); s_display_info_effective = p_effective; } @@ -584,7 +584,7 @@ bool MCUIDC::platform_displayinfocacheable(void) ////////// -bool MCUIDC::platform_getdisplays(bool p_effective, MCDisplay *&r_displays, uint32_t &r_count) +bool MCUIDC::platform_getdisplays(bool p_effective, MCDisplay *&r_displays, uint32_t &r_count, Boolean p_safe_area) { return false; } diff --git a/engine/src/uidc.h b/engine/src/uidc.h index 9f98e7abbde..905cc4a3fee 100644 --- a/engine/src/uidc.h +++ b/engine/src/uidc.h @@ -430,7 +430,7 @@ class MCUIDC uint2 getwidth(); uint2 getheight(); - uint4 getdisplays(MCDisplay const *& p_displays, bool effective); + uint4 getdisplays(MCDisplay const *& p_displays, bool effective, bool p_safe_area = false); // IM-2014-01-28: [[ HiDPI ]] Update the currently held display info, returning whether or not an changes have occurred void updatedisplayinfo(bool &r_changed); @@ -462,7 +462,7 @@ class MCUIDC virtual uint16_t platform_getwidth(void); virtual uint16_t platform_getheight(void); - virtual bool platform_getdisplays(bool p_effective, MCDisplay *&r_displays, uint32_t &r_count); + virtual bool platform_getdisplays(bool p_effective, MCDisplay *&r_displays, uint32_t &r_count, Boolean p_safe_area = false); virtual bool platform_getwindowgeometry(Window w, MCRectangle &drect); virtual void platform_boundrect(MCRectangle &rect, Boolean title, Window_mode m, Boolean resizable); virtual void platform_querymouse(int16_t &r_x, int16_t &r_y); diff --git a/engine/src/w32dc.h b/engine/src/w32dc.h index c1afc875fdb..248f8608122 100644 --- a/engine/src/w32dc.h +++ b/engine/src/w32dc.h @@ -214,7 +214,7 @@ class MCScreenDC : public MCUIDC // IM-2014-01-28: [[ HiDPI ]] Update device_* methods to platform-specific logical coord based methods virtual uint16_t platform_getwidth(void); virtual uint16_t platform_getheight(void); - virtual bool platform_getdisplays(bool p_effective, MCDisplay *&r_displays, uint32_t &r_count); + virtual bool platform_getdisplays(bool p_effective, MCDisplay *&r_displays, uint32_t &r_count, Boolean p_safe_area = false); virtual bool platform_displayinfocacheable(void); virtual bool platform_getwindowgeometry(Window w, MCRectangle &drect); virtual void platform_boundrect(MCRectangle &rect, Boolean title, Window_mode m, Boolean resizable); diff --git a/engine/src/w32dce.cpp b/engine/src/w32dce.cpp index a05b85fded2..80e522313de 100644 --- a/engine/src/w32dce.cpp +++ b/engine/src/w32dce.cpp @@ -120,7 +120,7 @@ static BOOL CALLBACK DescribeMonitorsCallback(HMONITOR p_monitor, HDC p_monitor_ } // IM-2014-01-28: [[ HiDPI ]] Refactored to handle display info caching in MCUIDC superclass -bool MCScreenDC::platform_getdisplays(bool p_effective, MCDisplay *&r_displays, uint32_t &r_count) +bool MCScreenDC::platform_getdisplays(bool p_effective, MCDisplay *&r_displays, uint32_t &r_count, Boolean p_safe_area) { bool t_success; t_success = true;