Skip to content

Commit 4bbc34a

Browse files
committed
feat: Enhance Window class with private implementation and size retrieval methods for macOS
1 parent 7587c25 commit 4bbc34a

File tree

6 files changed

+196
-12
lines changed

6 files changed

+196
-12
lines changed

CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,5 @@ add_subdirectory(src)
77

88
# Add example programs subdirectory
99
add_subdirectory(examples/display_example)
10+
add_subdirectory(examples/nswindow_example)
1011
add_subdirectory(examples/window_example)
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
cmake_minimum_required(VERSION 3.10)
2+
3+
project(nswindow_example VERSION 0.0.1 LANGUAGES CXX)
4+
5+
# Set C++ standard
6+
set(CMAKE_CXX_STANDARD 11)
7+
set(CMAKE_CXX_STANDARD_REQUIRED ON)
8+
9+
# Enable Objective-C++
10+
enable_language(OBJCXX)
11+
12+
# Add example program
13+
add_executable(nswindow_example
14+
"main.mm"
15+
)
16+
17+
# Link main library
18+
target_link_libraries(nswindow_example PRIVATE libnativeapi)
19+
20+
# Set example program properties
21+
set_target_properties(nswindow_example PROPERTIES
22+
OUTPUT_NAME "nswindow_example"
23+
)
24+
25+
# Set example program compile options (macOS only)
26+
if(APPLE)
27+
set_source_files_properties("main.mm"
28+
PROPERTIES
29+
COMPILE_FLAGS "-x objective-c++"
30+
)
31+
endif()

examples/nswindow_example/main.mm

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
#include <AppKit/AppKit.h>
2+
#import <Cocoa/Cocoa.h>
3+
#include <iostream>
4+
#include "nativeapi.h"
5+
6+
using nativeapi::Window;
7+
using nativeapi::WindowManager;
8+
9+
@interface AppDelegate : NSObject <NSApplicationDelegate>
10+
@property(strong) NSWindow* window;
11+
@end
12+
13+
@implementation AppDelegate
14+
15+
- (void)applicationDidFinishLaunching:(NSNotification*)notification {
16+
// Create a window
17+
NSRect frame = NSMakeRect(0, 0, 400, 300);
18+
self.window = [[NSWindow alloc]
19+
initWithContentRect:frame
20+
styleMask:NSWindowStyleMaskTitled | NSWindowStyleMaskClosable |
21+
NSWindowStyleMaskMiniaturizable | NSWindowStyleMaskResizable
22+
backing:NSBackingStoreBuffered
23+
defer:NO];
24+
[self.window setTitle:@"Native API Example"];
25+
[self.window center];
26+
[self.window makeKeyAndOrderFront:nil];
27+
[self.window makeMainWindow];
28+
[NSApp activateIgnoringOtherApps:YES];
29+
30+
// dispatch_async(dispatch_get_main_queue(), ^{
31+
32+
// });
33+
34+
// 延迟检查主窗口
35+
dispatch_async(dispatch_get_main_queue(), ^{
36+
NSLog(@"主窗口: %@", NSApp.mainWindow);
37+
NSLog(@"关键窗口: %@", NSApp.keyWindow);
38+
NSLog(@"所有窗口: %@", NSApp.windows);
39+
});
40+
41+
[[NSNotificationCenter defaultCenter]
42+
addObserverForName:NSWindowDidBecomeMainNotification
43+
object:nil
44+
queue:nil
45+
usingBlock:^(NSNotification* note) {
46+
NSWindow* mainWindow = [[NSApplication sharedApplication] mainWindow];
47+
NSLog(@"主窗口: %@", mainWindow);
48+
49+
// Initialize WindowManager
50+
WindowManager windowManager = WindowManager();
51+
52+
// Get current window information
53+
Window currentWindow = windowManager.GetCurrent();
54+
std::cout << "Current Window Information:" << std::endl;
55+
std::cout << "ID: " << currentWindow.id << std::endl;
56+
57+
// Get window size
58+
auto size = currentWindow.GetSize();
59+
std::cout << "Window Size: " << size.width << "x" << size.height << std::endl;
60+
61+
// Get all windows
62+
std::vector<Window> windowList = windowManager.GetAll();
63+
std::cout << "\nAll Windows Information:" << std::endl;
64+
for (size_t i = 0; i < windowList.size(); i++) {
65+
const Window& window = windowList[i];
66+
std::cout << "Window " << (i + 1) << ":" << std::endl;
67+
std::cout << "ID: " << window.id << std::endl;
68+
auto windowSize = window.GetSize();
69+
std::cout << "Size: " << windowSize.width << "x" << windowSize.height
70+
<< std::endl;
71+
}
72+
}];
73+
}
74+
75+
- (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication*)sender {
76+
return YES;
77+
}
78+
79+
@end
80+
81+
int main(int argc, const char* argv[]) {
82+
@autoreleasepool {
83+
NSApplication* app = [NSApplication sharedApplication];
84+
AppDelegate* delegate = [[AppDelegate alloc] init];
85+
[app setDelegate:delegate];
86+
[app run];
87+
}
88+
return 0;
89+
}

src/window.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,24 @@
11
#pragma once
22
#include <string>
3+
#include "geometry.h"
34

45
namespace nativeapi {
56

67
class Window {
78
public:
89
Window();
10+
Window(void* window); // Constructor that takes NSWindow*
911
virtual ~Window();
1012

1113
std::string id;
1214
std::string name;
15+
16+
void* GetNSWindow() const; // Returns NSWindow* on macOS
17+
Size GetSize() const; // Get window size
18+
19+
private:
20+
class Impl;
21+
Impl* pimpl_; // Pointer to implementation
1322
};
1423

1524
} // namespace nativeapi

src/window_macos.mm

Lines changed: 49 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,62 @@
11
#include "window.h"
22
#include "window_manager.h"
3+
#include <iostream>
34

45
// Import Cocoa headers
56
#import <Cocoa/Cocoa.h>
67

78
namespace nativeapi {
89

9-
Window::Window() {
10+
// Private implementation class
11+
class Window::Impl {
12+
public:
13+
Impl(NSWindow* window) : ns_window_(window) {}
14+
NSWindow* ns_window_;
15+
};
16+
17+
Window::Window() : pimpl_(nullptr) {
1018
id = "window1";
11-
name = "Window 1";
19+
std::cout << "Window created with null pimpl_" << std::endl;
1220
}
1321

14-
Window::~Window() {}
22+
Window::Window(void* window) : pimpl_(new Impl((NSWindow*)window)) {
23+
id = "window1";
24+
std::cout << "Window created with NSWindow: " << pimpl_->ns_window_ << std::endl;
25+
}
26+
27+
Window::~Window() {
28+
std::cout << "Window destroyed, pimpl_: " << pimpl_ << std::endl;
29+
delete pimpl_;
30+
}
31+
32+
void* Window::GetNSWindow() const {
33+
if (!pimpl_) {
34+
std::cout << "GetNSWindow: pimpl_ is null" << std::endl;
35+
return nullptr;
36+
}
37+
if (!pimpl_->ns_window_) {
38+
std::cout << "GetNSWindow: ns_window_ is null" << std::endl;
39+
return nullptr;
40+
}
41+
std::cout << "GetNSWindow: returning valid NSWindow pointer" << std::endl;
42+
return pimpl_->ns_window_;
43+
}
44+
45+
Size Window::GetSize() const {
46+
Size size = {0, 0};
47+
if (!pimpl_) {
48+
std::cout << "GetSize: pimpl_ is null" << std::endl;
49+
return size;
50+
}
51+
if (!pimpl_->ns_window_) {
52+
std::cout << "GetSize: ns_window_ is null" << std::endl;
53+
return size;
54+
}
55+
NSRect frame = [pimpl_->ns_window_ frame];
56+
size.width = static_cast<int>(frame.size.width);
57+
size.height = static_cast<int>(frame.size.height);
58+
std::cout << "GetSize: window size is " << size.width << "x" << size.height << std::endl;
59+
return size;
60+
}
1561

1662
} // namespace nativeapi

src/window_manager_macos.mm

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -20,23 +20,31 @@
2020

2121
Window WindowManager::GetCurrent() {
2222
NSApplication* app = [NSApplication sharedApplication];
23-
NSWindow* window = [app mainWindow];
24-
if (window == nil) {
23+
NSWindow* ns_window = [app mainWindow];
24+
if (ns_window == nil) {
2525
std::cerr << "No main window found." << std::endl;
2626
return Window();
2727
} else {
2828
std::cout << "Main window found." << std::endl;
29-
std::cout << "Window title: " << [[window title] UTF8String] << std::endl;
29+
std::cout << "Window title: " << [[ns_window title] UTF8String] << std::endl;
3030
}
31-
return *new Window();
31+
return *new Window(ns_window);
3232
}
3333

3434
std::vector<Window> WindowManager::GetAll() {
35-
std::vector<Window> displayList;
36-
37-
displayList.push_back(GetCurrent());
38-
39-
return displayList;
35+
std::vector<Window> windowList;
36+
NSApplication* app = [NSApplication sharedApplication];
37+
NSArray* windows = [app windows];
38+
for (NSWindow* ns_window in windows) {
39+
if ([ns_window isVisible]) {
40+
NSRect frame = [ns_window frame];
41+
std::cout << "Window title: " << [[ns_window title] UTF8String] << std::endl;
42+
std::cout << "Window size: " << frame.size.width << "x" << frame.size.height
43+
<< std::endl;
44+
windowList.push_back(*new Window(ns_window));
45+
}
46+
}
47+
return windowList;
4048
}
4149

4250
} // namespace nativeapi

0 commit comments

Comments
 (0)