11#include < cstring>
22#include < iostream>
3+ #include < set>
34#include < string>
4- #include " screen_retriever.h"
5+ #include < vector>
6+
7+ #include " display.h"
8+ #include " display_manager.h"
59
610// Import Cocoa headers
711#import < Cocoa/Cocoa.h>
812
913namespace nativeapi {
1014
11- // Helper function to convert NSString to char*
12- static char * ConvertNSStringToCString (NSString * nsString) {
13- if (nsString == nil ) {
14- return strdup (" " );
15- }
16- const char * cString = [nsString UTF8String ];
17- return cString ? strdup (cString) : strdup (" " );
18- }
19-
20- static Display CreateDisplayFromNSScreen (NSScreen * screen, bool isFirstScreen) {
15+ static Display CreateDisplayFromNSScreen (NSScreen * screen, bool isPrimary) {
2116 Display display;
2217
2318 // Get screen details
@@ -29,17 +24,17 @@ static Display CreateDisplayFromNSScreen(NSScreen* screen, bool isFirstScreen) {
2924 CGDirectDisplayID displayID =
3025 [[[screen deviceDescription ] objectForKey: @" NSScreenNumber" ] unsignedIntValue ];
3126 NSString * screenId = [NSString stringWithFormat: @" %@ " , @(displayID)];
32- display.id = ConvertNSStringToCString ( screenId) ;
27+ display.id = [ screenId UTF8String ] ;
3328
3429 // Set display name - use localizedName on macOS 10.15+
3530 NSString * displayName;
3631 if (@available (macOS 10.15 , *)) {
3732 displayName = [screen localizedName ];
3833 } else {
39- displayName = isFirstScreen ? @" Primary Display "
40- : [NSString stringWithFormat: @" Display %@ " , @(displayID)];
34+ displayName =
35+ isPrimary ? @" Primary Display " : [NSString stringWithFormat: @" Display %@ " , @(displayID)];
4136 }
42- display.name = ConvertNSStringToCString ( displayName) ;
37+ display.name = [ displayName UTF8String ] ;
4338
4439 // Set size and position properties
4540 display.width = frame.size .width ;
@@ -55,57 +50,70 @@ static Display CreateDisplayFromNSScreen(NSScreen* screen, bool isFirstScreen) {
5550
5651id displayObserver_;
5752
58- ScreenRetriever::ScreenRetriever () {
59- // Store initial display configuration
60- current_displays_ = GetAllDisplays ();
61-
53+ DisplayManager::DisplayManager () {
54+ displays_ = GetAll ();
6255 // Set up display configuration change observer
6356 displayObserver_ = [[NSNotificationCenter defaultCenter ]
6457 addObserverForName: NSApplicationDidChangeScreenParametersNotification
6558 object: nil
6659 queue: [NSOperationQueue mainQueue ]
6760 usingBlock: ^(NSNotification * notification) {
68- HandleDisplayChange ();
61+ auto old_displays = displays_;
62+ auto new_displays = GetAll ();
63+
64+ // Find added displays
65+ std::set<std::string> old_ids;
66+ for (const auto & d : old_displays)
67+ old_ids.insert (d.id );
68+ for (const auto & d : new_displays) {
69+ if (old_ids.find (d.id ) == old_ids.end ()) {
70+ NotifyDisplayAdded (d);
71+ }
72+ }
73+
74+ // Find removed displays
75+ std::set<std::string> new_ids;
76+ for (const auto & d : new_displays)
77+ new_ids.insert (d.id );
78+ for (const auto & d : old_displays) {
79+ if (new_ids.find (d.id ) == new_ids.end ()) {
80+ NotifyDisplayRemoved (d);
81+ }
82+ }
83+
84+ displays_ = std::move (new_displays);
6985 }];
7086}
7187
72- ScreenRetriever::~ScreenRetriever () {
73- // Remove observer
88+ DisplayManager::~DisplayManager () {
7489 if (displayObserver_) {
7590 [[NSNotificationCenter defaultCenter ] removeObserver: displayObserver_];
7691 }
77- // Note: cursor observer is automatically cleaned up when the run loop source is removed
7892}
7993
80- Point ScreenRetriever::GetCursorScreenPoint () {
81- Point point;
82-
83- // Get the current mouse position
94+ Point DisplayManager::GetCursorPosition () {
8495 NSPoint mouseLocation = [NSEvent mouseLocation ];
96+ Point point;
8597 point.x = mouseLocation.x ;
8698 point.y = mouseLocation.y ;
87-
8899 return point;
89100}
90101
91- Display ScreenRetriever::GetPrimaryDisplay () {
92- // Get the primary display (first screen)
93- NSArray <NSScreen *>* screens = [NSScreen screens ];
94- return CreateDisplayFromNSScreen (screens[0 ], true );
95- }
96-
97- std::vector<Display> ScreenRetriever::GetAllDisplays () {
102+ std::vector<Display> DisplayManager::GetAll () {
98103 std::vector<Display> displayList;
99-
100- // Get all screens
101104 NSArray <NSScreen *>* screens = [NSScreen screens ];
102- bool isFirstScreen = true ;
105+ bool isPrimary = true ;
103106 for (NSScreen * screen in screens) {
104- displayList.push_back (CreateDisplayFromNSScreen (screen, isFirstScreen ));
105- isFirstScreen = false ; // Only the first screen is the main screen
107+ displayList.push_back (CreateDisplayFromNSScreen (screen, isPrimary ));
108+ isPrimary = false ; // Only the first NSScreen is the primary display
106109 }
107-
108110 return displayList;
109111}
110112
113+ Display DisplayManager::GetPrimary () {
114+ // Get the primary display (first NSScreen)
115+ NSArray <NSScreen *>* screens = [NSScreen screens ];
116+ return CreateDisplayFromNSScreen (screens[0 ], true );
117+ }
118+
111119} // namespace nativeapi
0 commit comments