Skip to content

Commit 9a6ee91

Browse files
committed
wip: Rename ScreenRetriever to DisplayManager
1 parent 7211f18 commit 9a6ee91

15 files changed

+163
-198
lines changed

.github/workflows/build.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,4 +50,4 @@ jobs:
5050
uses: actions/upload-artifact@v4
5151
with:
5252
name: examples-${{ matrix.platform }}
53-
path: build/examples/screen_info/
53+
path: build/examples/display_example/

CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,5 @@ project(libnativeapi_library VERSION 0.0.1 LANGUAGES CXX)
66
add_subdirectory(src)
77

88
# Add example programs subdirectory
9-
add_subdirectory(examples/screen_info)
9+
add_subdirectory(examples/display_example)
1010
add_subdirectory(examples/window_example)

examples/screen_info/CMakeLists.txt renamed to examples/display_example/CMakeLists.txt

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,22 @@
11
cmake_minimum_required(VERSION 3.10)
22

3-
project(screen_info_example VERSION 0.0.1 LANGUAGES CXX)
3+
project(display_example VERSION 0.0.1 LANGUAGES CXX)
44

55
# Set C++ standard
66
set(CMAKE_CXX_STANDARD 11)
77
set(CMAKE_CXX_STANDARD_REQUIRED ON)
88

99
# Add example program
10-
add_executable(screen_info_example
10+
add_executable(display_example
1111
"main.cpp"
1212
)
1313

1414
# Link main library
15-
target_link_libraries(screen_info_example PRIVATE libnativeapi)
15+
target_link_libraries(display_example PRIVATE libnativeapi)
1616

1717
# Set example program properties
18-
set_target_properties(screen_info_example PROPERTIES
19-
OUTPUT_NAME "screen_info_example"
18+
set_target_properties(display_example PROPERTIES
19+
OUTPUT_NAME "display_example"
2020
)
2121

2222
# Set example program compile options (macOS only)

examples/screen_info/main.cpp renamed to examples/display_example/main.cpp

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,13 @@
33

44
using nativeapi::Display;
55
using nativeapi::Point;
6-
using nativeapi::ScreenEventType;
7-
using nativeapi::ScreenRetriever;
6+
using nativeapi::DisplayManager;
87

98
int main() {
10-
ScreenRetriever screenRetriever = ScreenRetriever();
9+
DisplayManager displayManager = DisplayManager();
1110

1211
// Get primary display information
13-
Display primaryDisplay = screenRetriever.GetPrimaryDisplay();
12+
Display primaryDisplay = displayManager.GetPrimary();
1413
std::cout << "Primary Display Information:" << std::endl;
1514
std::cout << "ID: " << primaryDisplay.id << std::endl;
1615
std::cout << "Name: " << primaryDisplay.name << std::endl;
@@ -24,7 +23,7 @@ int main() {
2423
std::cout << std::endl;
2524

2625
// Get all displays information
27-
std::vector<Display> allDisplays = screenRetriever.GetAllDisplays();
26+
std::vector<Display> allDisplays = displayManager.GetAll();
2827
std::cout << "All Displays Information:" << std::endl;
2928
for (int i = 0; i < allDisplays.size(); i++) {
3029
Display& display = allDisplays[i];
@@ -42,8 +41,8 @@ int main() {
4241
}
4342

4443
// Get cursor position
45-
Point cursorPoint = screenRetriever.GetCursorScreenPoint();
46-
std::cout << "Current Cursor Position: (" << cursorPoint.x << ", "
47-
<< cursorPoint.y << ")" << std::endl;
44+
Point cursorPosition = displayManager.GetCursorPosition();
45+
std::cout << "Current Cursor Position: (" << cursorPosition.x << ", "
46+
<< cursorPosition.y << ")" << std::endl;
4847
return 0;
4948
}

include/nativeapi.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#pragma once
22

33
#include "../src/display.h"
4+
#include "../src/display_manager.h"
45
#include "../src/geometry.h"
5-
#include "../src/screen_retriever.h"
66
#include "../src/window.h"
77
#include "../src/window_manager.h"

src/display_manager.cpp

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
#include <set>
2+
3+
#include "display_manager.h"
4+
5+
namespace nativeapi {
6+
7+
void DisplayManager::AddListener(DisplayListener* listener) {
8+
listeners_.push_back(listener);
9+
}
10+
11+
void DisplayManager::RemoveListener(DisplayListener* listener) {
12+
listeners_.erase(std::remove(listeners_.begin(), listeners_.end(), listener),
13+
listeners_.end());
14+
}
15+
16+
void DisplayManager::NotifyDisplayAdded(const Display& display) {
17+
for (const auto& listener : listeners_) {
18+
listener->OnDisplayAdded(display);
19+
}
20+
}
21+
22+
void DisplayManager::NotifyDisplayRemoved(const Display& display) {
23+
for (const auto& listener : listeners_) {
24+
listener->OnDisplayRemoved(display);
25+
}
26+
}
27+
28+
} // namespace nativeapi

src/display_manager.h

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
#pragma once
2+
3+
#include <cstdint>
4+
#include <functional>
5+
#include <map>
6+
#include <vector>
7+
8+
#include "display.h"
9+
#include "geometry.h"
10+
11+
namespace nativeapi {
12+
13+
// DisplayListener is an interface that can be implemented by classes that want
14+
// to listen for display events.
15+
class DisplayListener {
16+
public:
17+
virtual void OnDisplayAdded(const Display& display) = 0;
18+
virtual void OnDisplayRemoved(const Display& display) = 0;
19+
};
20+
21+
// DisplayManager is a singleton that manages all displays on the system.
22+
class DisplayManager {
23+
public:
24+
DisplayManager();
25+
virtual ~DisplayManager();
26+
27+
// Get the current cursor position
28+
Point GetCursorPosition();
29+
30+
// Get all displays information
31+
std::vector<Display> GetAll();
32+
33+
// Get the primary display information
34+
Display GetPrimary();
35+
36+
// Add a listener to the display manager
37+
void AddListener(DisplayListener* listener);
38+
39+
// Remove a listener from the display manager
40+
void RemoveListener(DisplayListener* listener);
41+
42+
private:
43+
std::vector<Display> displays_;
44+
std::vector<DisplayListener*> listeners_;
45+
void NotifyDisplayAdded(const Display& display);
46+
void NotifyDisplayRemoved(const Display& display);
47+
};
48+
49+
} // namespace nativeapi

src/screen_retriever_linux.cpp renamed to src/display_manager_linux.cpp

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#include <gtk/gtk.h>
22
#include <iostream>
3-
#include "screen_retriever.h"
3+
#include "display_manager.h"
44

55
namespace nativeapi {
66

@@ -30,18 +30,18 @@ static Display CreateDisplayFromGdkMonitor(GdkMonitor* monitor,
3030
return display;
3131
}
3232

33-
ScreenRetriever::ScreenRetriever() {
33+
DisplayManager::DisplayManager() {
3434
gtk_init(nullptr, nullptr);
3535
// Constructor implementation
36-
std::cout << "ScreenRetriever initialized" << std::endl;
36+
std::cout << "DisplayManager initialized" << std::endl;
3737
}
3838

39-
ScreenRetriever::~ScreenRetriever() {
39+
DisplayManager::~DisplayManager() {
4040
// Destructor implementation
41-
std::cout << "ScreenRetriever destroyed" << std::endl;
41+
std::cout << "DisplayManager destroyed" << std::endl;
4242
}
4343

44-
Point ScreenRetriever::GetCursorScreenPoint() {
44+
Point DisplayManager::GetCursorPosition() {
4545
GdkDisplay* display = gdk_display_get_default();
4646
GdkSeat* seat = gdk_display_get_default_seat(display);
4747
GdkDevice* pointer = gdk_seat_get_pointer(seat);
@@ -56,7 +56,7 @@ Point ScreenRetriever::GetCursorScreenPoint() {
5656
return point;
5757
}
5858

59-
Display ScreenRetriever::GetPrimaryDisplay() {
59+
Display DisplayManager::GetPrimary() {
6060
GdkDisplay* display = gdk_display_get_default();
6161
GdkMonitor* monitor = gdk_display_get_primary_monitor(display);
6262

@@ -71,10 +71,10 @@ Display ScreenRetriever::GetPrimaryDisplay() {
7171
return CreateDisplayFromGdkMonitor(monitor, true);
7272
}
7373

74-
std::vector<Display> ScreenRetriever::GetAllDisplays() {
74+
std::vector<Display> DisplayManager::GetAll() {
7575
// Empty implementation
7676
std::vector<Display> displayList;
77-
displayList.push_back(GetPrimaryDisplay());
77+
displayList.push_back(GetPrimary());
7878
return displayList;
7979
}
8080

Lines changed: 49 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,18 @@
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

913
namespace 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

5651
id 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

Comments
 (0)