aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiguel Borges de Freitas <92enen@gmail.com>2023-02-22 10:01:39 +0000
committerGitHub <noreply@github.com>2023-02-22 10:01:39 +0000
commitb74469418028d12649b69c59de68c286c988f919 (patch)
tree72336ccf128005f469596a00c0282b494c511d5f
parent218662d4c3bd5dd0eb6ba4d046c54a24a88c3e36 (diff)
parentf8b7b7e7747e62005b3d12b3287b95cffc2fcb6f (diff)
Merge pull request #22746 from enen92/windowing_native_osx
[macos][nativewindowing] Improvements for multi-screen setups
-rw-r--r--system/settings/darwin_osx.xml15
-rw-r--r--xbmc/windowing/osx/OpenGL/OSXGLWindow.mm29
-rw-r--r--xbmc/windowing/osx/WinSystemOSX.mm116
3 files changed, 120 insertions, 40 deletions
diff --git a/system/settings/darwin_osx.xml b/system/settings/darwin_osx.xml
index 5d73f3be53..ecf488a86c 100644
--- a/system/settings/darwin_osx.xml
+++ b/system/settings/darwin_osx.xml
@@ -9,4 +9,19 @@
</group>
</category>
</section>
+ <section id="interface" label="14206" help="38102">
+ <category id="window" label="0" help="36135">
+ <visible>false</visible>
+ <group id="1">
+ <setting id="window.top" type="integer" label="0" help="36136">
+ <level>4</level>
+ <default>0</default>
+ </setting>
+ <setting id="window.left" type="integer" label="0" help="36136">
+ <level>4</level>
+ <default>0</default>
+ </setting>
+ </group>
+ </category>
+ </section>
</settings>
diff --git a/xbmc/windowing/osx/OpenGL/OSXGLWindow.mm b/xbmc/windowing/osx/OpenGL/OSXGLWindow.mm
index ad5ff771c2..c7028e7f8e 100644
--- a/xbmc/windowing/osx/OpenGL/OSXGLWindow.mm
+++ b/xbmc/windowing/osx/OpenGL/OSXGLWindow.mm
@@ -64,19 +64,17 @@
- (void)windowDidMove:(NSNotification*)aNotification
{
- NSOpenGLContext* context = NSOpenGLContext.currentContext;
- if (context)
+ if (self.contentView)
{
- if (context.view)
+ NSPoint window_origin = [self.contentView frame].origin;
+ XBMC_Event newEvent = {};
+ newEvent.type = XBMC_VIDEOMOVE;
+ newEvent.move.x = window_origin.x;
+ newEvent.move.y = window_origin.y;
+ std::shared_ptr<CAppInboundProtocol> appPort = CServiceBroker::GetAppPort();
+ if (appPort)
{
- NSPoint window_origin = [[[context view] window] frame].origin;
- XBMC_Event newEvent = {};
- newEvent.type = XBMC_VIDEOMOVE;
- newEvent.move.x = window_origin.x;
- newEvent.move.y = window_origin.y;
- std::shared_ptr<CAppInboundProtocol> appPort = CServiceBroker::GetAppPort();
- if (appPort)
- appPort->OnEvent(newEvent);
+ appPort->OnEvent(newEvent);
}
}
}
@@ -136,10 +134,11 @@
- (void)windowDidChangeScreen:(NSNotification*)notification
{
- // user has moved the window to a
- // different screen
- // if (CServiceBroker::GetWinSystem()->IsFullScreen())
- // CServiceBroker::GetWinSystem()->SetMovedToOtherScreen(true);
+ // user has moved the window to a different screen
+ CWinSystemOSX* winSystem = dynamic_cast<CWinSystemOSX*>(CServiceBroker::GetWinSystem());
+ if (!winSystem)
+ return;
+ winSystem->WindowChangedScreen();
}
- (NSSize)windowWillResize:(NSWindow*)sender toSize:(NSSize)frameSize
diff --git a/xbmc/windowing/osx/WinSystemOSX.mm b/xbmc/windowing/osx/WinSystemOSX.mm
index 023d4ce07e..be6a8efdaf 100644
--- a/xbmc/windowing/osx/WinSystemOSX.mm
+++ b/xbmc/windowing/osx/WinSystemOSX.mm
@@ -58,7 +58,16 @@ using namespace MESSAGING;
using namespace WINDOWING;
using namespace std::chrono_literals;
-#define MAX_DISPLAYS 32
+namespace
+{
+constexpr int MAX_DISPLAYS = 32;
+constexpr const char* DEFAULT_SCREEN_NAME = "Default";
+//! MacOS specific window top position setting
+constexpr const char* SETTING_WINDOW_TOP = "window.top";
+//! MacOS specific window left position setting
+constexpr const char* SETTING_WINDOW_LEFT = "window.left";
+} // namespace
+
static NSWindow* blankingWindows[MAX_DISPLAYS];
size_t DisplayBitsPerPixelForMode(CGDisplayModeRef mode)
@@ -110,7 +119,7 @@ CGDirectDisplayID GetDisplayID(NSUInteger screen_index)
#pragma mark - GetScreenName
-NSString* screenNameForDisplay(NSUInteger screenIdx)
+NSString* GetScreenName(NSUInteger screenIdx)
{
NSString* screenName;
const CGDirectDisplayID displayID = GetDisplayID(screenIdx);
@@ -144,6 +153,19 @@ NSString* screenNameForDisplay(NSUInteger screenIdx)
}
}
}
+ return screenName;
+}
+
+NSString* screenNameForDisplay(NSUInteger screenIdx)
+{
+ // screen id 0 is always called "Default"
+ if (screenIdx == 0)
+ {
+ return @(DEFAULT_SCREEN_NAME);
+ }
+
+ const CGDirectDisplayID displayID = GetDisplayID(screenIdx);
+ NSString* screenName = GetScreenName(screenIdx);
if (screenName == nil)
{
@@ -641,6 +663,16 @@ bool CWinSystemOSX::DestroyWindowSystem()
bool CWinSystemOSX::CreateNewWindow(const std::string& name, bool fullScreen, RESOLUTION_INFO& res)
{
+ // find the screen where the application started the last time. It'd be the default screen if the
+ // screen index is not found/available.
+ const std::shared_ptr<CSettings> settings = CServiceBroker::GetSettingsComponent()->GetSettings();
+ m_lastDisplayNr = GetDisplayIndex(settings->GetString(CSettings::SETTING_VIDEOSCREEN_MONITOR));
+ NSScreen* screen = nil;
+ if (m_lastDisplayNr < NSScreen.screens.count)
+ {
+ screen = [NSScreen.screens objectAtIndex:m_lastDisplayNr];
+ }
+
// force initial window creation to be windowed, if fullscreen, it will switch to it below
// fixes the white screen of death if starting fullscreen and switching to windowed.
RESOLUTION_INFO resInfo = CDisplaySettings::GetInstance().GetResolutionInfo(RES_WINDOW);
@@ -684,6 +716,35 @@ bool CWinSystemOSX::CreateNewWindow(const std::string& name, bool fullScreen, RE
// associate with current window
[appWindow setContentView:view];
+
+ // set the window to the appropriate screen and screen position
+ if (screen)
+ {
+ if (m_bFullScreen)
+ {
+ [appWindow setFrameOrigin:screen.frame.origin];
+ }
+ else
+ {
+ // if there are stored window positions use that as the origin point
+ const int top = settings->GetInt(SETTING_WINDOW_TOP);
+ const int left = settings->GetInt(SETTING_WINDOW_LEFT);
+
+ NSPoint windowPos;
+ if (top != 0 || left != 0)
+ {
+ windowPos = NSMakePoint(left, top);
+ }
+ else
+ {
+ // otherwise center the window on the screen
+ windowPos =
+ NSMakePoint(screen.frame.origin.x + screen.frame.size.width / 2 - m_nWidth / 2,
+ screen.frame.origin.y + screen.frame.size.height / 2 - m_nHeight / 2);
+ }
+ [appWindow setFrameOrigin:windowPos];
+ }
+ }
});
[view.getGLContext makeCurrentContext];
@@ -1169,6 +1230,16 @@ void CWinSystemOSX::NotifyAppFocusChange(bool bGaining)
void CWinSystemOSX::OnMove(int x, int y)
{
+ // check if the current screen/monitor settings needs to be updated
+ const std::shared_ptr<CSettings> settings = CServiceBroker::GetSettingsComponent()->GetSettings();
+ const std::string storedScreenName = settings->GetString(CSettings::SETTING_VIDEOSCREEN_MONITOR);
+ const std::string currentScreenName = screenNameForDisplay(m_lastDisplayNr).UTF8String;
+ if (storedScreenName != currentScreenName)
+ {
+ CDisplaySettings::GetInstance().SetMonitor(currentScreenName);
+ }
+
+ // check if refresh rate needs to be updated
static double oldRefreshRate = m_refreshRate;
Cocoa_CVDisplayLinkUpdate();
@@ -1180,36 +1251,31 @@ void CWinSystemOSX::OnMove(int x, int y)
oldRefreshRate = m_refreshRate;
// send a message so that videoresolution (and refreshrate) is changed
- NSWindow* win = m_appWindow;
- NSRect frame = win.contentView.frame;
- CServiceBroker::GetAppMessenger()->PostMsg(TMSG_VIDEORESIZE, frame.size.width,
- frame.size.height);
+ dispatch_sync(dispatch_get_main_queue(), ^{
+ NSWindow* win = m_appWindow;
+ NSRect frame = win.contentView.frame;
+ CServiceBroker::GetAppMessenger()->PostMsg(TMSG_VIDEORESIZE, frame.size.width,
+ frame.size.height);
+ });
+ }
+ // store window position in window mode
+ if (!m_bFullScreen)
+ {
+ dispatch_sync(dispatch_get_main_queue(), ^{
+ settings->SetInt(SETTING_WINDOW_LEFT, m_appWindow.frame.origin.x);
+ settings->SetInt(SETTING_WINDOW_TOP, m_appWindow.frame.origin.y);
+ settings->Save();
+ });
}
}
void CWinSystemOSX::WindowChangedScreen()
{
- // user has moved the window to a
- // different screen
- NSOpenGLContext* context = [NSOpenGLContext currentContext];
- m_lastDisplayNr = 0;
-
// if we are here the user dragged the window to a different
// screen and we return the screen of the window
- if (context)
+ if (m_appWindow)
{
- NSView* view;
-
- view = context.view;
- if (view)
- {
- NSWindow* window;
- window = view.window;
- if (window)
- {
- m_lastDisplayNr = GetDisplayIndex(GetDisplayIDFromScreen(window.screen));
- }
- }
+ m_lastDisplayNr = GetDisplayIndex(GetDisplayIDFromScreen(m_appWindow.screen));
}
}
@@ -1259,7 +1325,7 @@ std::unique_ptr<CVideoSync> CWinSystemOSX::GetVideoSync(void* clock)
std::vector<std::string> CWinSystemOSX::GetConnectedOutputs()
{
std::vector<std::string> outputs;
- outputs.push_back("Default");
+ outputs.push_back(DEFAULT_SCREEN_NAME);
// screen 0 is always the "Default" setting, avoid duplicating the available
// screens here.