-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathwindow_manager_linux.cpp
More file actions
184 lines (152 loc) · 4.9 KB
/
window_manager_linux.cpp
File metadata and controls
184 lines (152 loc) · 4.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
#include <cstring>
#include <iostream>
#include <string>
#include "../../window.h"
#include "../../window_manager.h"
// Import GTK headers
#include <gtk/gtk.h>
#include <gdk/gdk.h>
namespace nativeapi {
// Private implementation for Linux (stub for now)
class WindowManager::WindowManagerImpl {
public:
WindowManagerImpl(WindowManager* manager) : manager_(manager) {}
~WindowManagerImpl() {}
void SetupEventMonitoring() {
// TODO: Implement Linux-specific event monitoring using GTK signals
}
void CleanupEventMonitoring() {
// TODO: Implement Linux-specific cleanup
}
private:
WindowManager* manager_;
};
WindowManager::WindowManager() : impl_(std::make_unique<WindowManagerImpl>(this)) {
// Try to initialize GTK if not already initialized
// In headless environments, this may fail, which is acceptable
if (!gdk_display_get_default()) {
// Temporarily redirect stderr to suppress GTK warnings in headless environments
FILE* original_stderr = stderr;
freopen("/dev/null", "w", stderr);
gboolean gtk_result = gtk_init_check(nullptr, nullptr);
// Restore stderr
fflush(stderr);
freopen("/dev/tty", "w", stderr);
stderr = original_stderr;
// gtk_init_check returns FALSE if initialization failed (e.g., no display)
// This is acceptable for headless environments
}
SetupEventMonitoring();
}
WindowManager::~WindowManager() {
CleanupEventMonitoring();
}
void WindowManager::SetupEventMonitoring() {
impl_->SetupEventMonitoring();
}
void WindowManager::CleanupEventMonitoring() {
impl_->CleanupEventMonitoring();
}
void WindowManager::DispatchWindowEvent(const Event& event) {
event_dispatcher_.DispatchSync(event);
}
std::shared_ptr<Window> WindowManager::Get(WindowID id) {
auto it = windows_.find(id);
if (it != windows_.end()) {
return it->second;
}
// Try to find the window by ID in the current display
GdkDisplay* display = gdk_display_get_default();
if (!display) {
return nullptr;
}
// Get all toplevel windows
GList* toplevels = gtk_window_list_toplevels();
for (GList* l = toplevels; l != nullptr; l = l->next) {
GtkWindow* gtk_window = GTK_WINDOW(l->data);
GdkWindow* gdk_window = gtk_widget_get_window(GTK_WIDGET(gtk_window));
if (gdk_window && (WindowID)gdk_window == id) {
auto window = std::make_shared<Window>((void*)gdk_window);
windows_[id] = window;
g_list_free(toplevels);
return window;
}
}
g_list_free(toplevels);
return nullptr;
}
std::vector<std::shared_ptr<Window>> WindowManager::GetAll() {
std::vector<std::shared_ptr<Window>> windows;
GdkDisplay* display = gdk_display_get_default();
if (!display) {
return windows;
}
// Get all toplevel windows
GList* toplevels = gtk_window_list_toplevels();
for (GList* l = toplevels; l != nullptr; l = l->next) {
GtkWindow* gtk_window = GTK_WINDOW(l->data);
GdkWindow* gdk_window = gtk_widget_get_window(GTK_WIDGET(gtk_window));
if (gdk_window) {
WindowID window_id = (WindowID)gdk_window;
auto it = windows_.find(window_id);
if (it == windows_.end()) {
auto window = std::make_shared<Window>((void*)gdk_window);
windows_[window_id] = window;
}
}
}
g_list_free(toplevels);
// Return all cached windows
for (auto& window : windows_) {
windows.push_back(window.second);
}
return windows;
}
std::shared_ptr<Window> WindowManager::GetCurrent() {
GdkDisplay* display = gdk_display_get_default();
if (!display) {
return nullptr;
}
// Try to get the focused window
GdkSeat* seat = gdk_display_get_default_seat(display);
if (seat) {
GdkDevice* keyboard = gdk_seat_get_keyboard(seat);
if (keyboard) {
GdkWindow* focused_window = gdk_device_get_window_at_position(keyboard, nullptr, nullptr);
if (focused_window) {
WindowID window_id = (WindowID)focused_window;
return Get(window_id);
}
}
}
// Fallback: get the first visible window
GList* toplevels = gtk_window_list_toplevels();
for (GList* l = toplevels; l != nullptr; l = l->next) {
GtkWindow* gtk_window = GTK_WINDOW(l->data);
if (gtk_widget_get_visible(GTK_WIDGET(gtk_window))) {
GdkWindow* gdk_window = gtk_widget_get_window(GTK_WIDGET(gtk_window));
if (gdk_window) {
WindowID window_id = (WindowID)gdk_window;
g_list_free(toplevels);
return Get(window_id);
}
}
}
g_list_free(toplevels);
return nullptr;
}
std::shared_ptr<Window> WindowManager::Create(const WindowOptions& options) {
// TODO: Implement Linux window creation using GTK
// For now, return nullptr as this is a stub implementation
return nullptr;
}
bool WindowManager::Destroy(WindowID id) {
auto it = windows_.find(id);
if (it != windows_.end()) {
// TODO: Implement proper GTK window destruction
windows_.erase(it);
return true;
}
return false;
}
} // namespace nativeapi