Skip to content

Commit b24a33c

Browse files
committed
Add window show/hide hooks for Linux and Windows
Implemented pre-show and pre-hide hooks in WindowManager for both Linux (GTK) and Windows platforms. Hooks are invoked on window show/hide events, allowing custom logic to be executed before the window is shown or hidden. Updated internal implementation to store and call these hooks as needed.
1 parent 0285b9b commit b24a33c

File tree

2 files changed

+80
-19
lines changed

2 files changed

+80
-19
lines changed

src/platform/linux/window_manager_linux.cpp

Lines changed: 55 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,33 @@ static GdkWindow* FindGdkWindowById(WindowId id) {
4848
return nullptr;
4949
}
5050

51+
// GTK signal callbacks to invoke hooks
52+
static gboolean OnGtkMapEvent(GtkWidget* widget, GdkEvent* event, gpointer user_data) {
53+
(void)event;
54+
(void)user_data;
55+
auto& manager = WindowManager::GetInstance();
56+
GdkWindow* gdk_window = gtk_widget_get_window(widget);
57+
if (gdk_window) {
58+
WindowId id = GetOrCreateWindowId(gdk_window);
59+
manager.InvokeWillShowHook(id);
60+
}
61+
// Return FALSE to propagate event further
62+
return FALSE;
63+
}
64+
65+
static gboolean OnGtkUnmapEvent(GtkWidget* widget, GdkEvent* event, gpointer user_data) {
66+
(void)event;
67+
(void)user_data;
68+
auto& manager = WindowManager::GetInstance();
69+
GdkWindow* gdk_window = gtk_widget_get_window(widget);
70+
if (gdk_window) {
71+
WindowId id = GetOrCreateWindowId(gdk_window);
72+
manager.InvokeWillHideHook(id);
73+
}
74+
// Return FALSE to propagate event further
75+
return FALSE;
76+
}
77+
5178
// Private implementation for Linux (stub for now)
5279
class WindowManager::Impl {
5380
public:
@@ -64,6 +91,11 @@ class WindowManager::Impl {
6491

6592
private:
6693
WindowManager* manager_;
94+
// Optional pre-show/hide hooks
95+
std::optional<WindowManager::WindowWillShowHook> will_show_hook_;
96+
std::optional<WindowManager::WindowWillHideHook> will_hide_hook_;
97+
98+
friend class WindowManager;
6799
};
68100

69101
WindowManager::WindowManager() : pimpl_(std::make_unique<Impl>(this)) {
@@ -218,6 +250,10 @@ std::shared_ptr<Window> WindowManager::Create(const WindowOptions& options) {
218250
return nullptr;
219251
}
220252

253+
// Connect map/unmap events to invoke hooks
254+
g_signal_connect(G_OBJECT(gtk_window), "map-event", G_CALLBACK(OnGtkMapEvent), nullptr);
255+
g_signal_connect(G_OBJECT(gtk_window), "unmap-event", G_CALLBACK(OnGtkUnmapEvent), nullptr);
256+
221257
// Set window properties from options
222258
if (!options.title.empty()) {
223259
gtk_window_set_title(GTK_WINDOW(gtk_window), options.title.c_str());
@@ -249,30 +285,30 @@ std::shared_ptr<Window> WindowManager::Create(const WindowOptions& options) {
249285
gtk_window_set_position(GTK_WINDOW(gtk_window), GTK_WIN_POS_CENTER);
250286
}
251287

252-
// Show the window
253-
gtk_widget_show(gtk_window);
254-
255-
// Get the GdkWindow after the widget is realized
256-
GdkWindow* gdk_window = gtk_widget_get_window(gtk_window);
257-
if (!gdk_window) {
258-
// If window is not yet realized, realize it first
288+
// Realize to ensure GdkWindow exists before show, so we can derive ID and invoke hook
289+
if (!gtk_widget_get_realized(gtk_window)) {
259290
gtk_widget_realize(gtk_window);
260-
gdk_window = gtk_widget_get_window(gtk_window);
261291
}
262292

293+
// Obtain GdkWindow and compute WindowId
294+
GdkWindow* gdk_window = gtk_widget_get_window(gtk_window);
263295
if (!gdk_window) {
264296
std::cerr << "Failed to get GdkWindow from GTK widget" << std::endl;
265297
gtk_widget_destroy(gtk_window);
266298
return nullptr;
267299
}
268300

269-
// Create our Window wrapper
301+
// Create our Window wrapper and cache before showing
270302
auto window = std::make_shared<Window>((void*)gdk_window);
271303
WindowId window_id = GetOrCreateWindowId(gdk_window);
272-
273-
// Store in our cache
274304
windows_[window_id] = window;
275305

306+
// Invoke pre-show hook if set
307+
InvokeWillShowHook(window_id);
308+
309+
// Show the window after invoking hook
310+
gtk_widget_show(gtk_window);
311+
276312
std::cout << "Created window with ID: " << window_id << std::endl;
277313

278314
return window;
@@ -289,19 +325,23 @@ bool WindowManager::Destroy(WindowId id) {
289325
}
290326

291327
void WindowManager::SetWillShowHook(std::optional<WindowWillShowHook> hook) {
292-
// Empty implementation
328+
pimpl_->will_show_hook_ = std::move(hook);
293329
}
294330

295331
void WindowManager::SetWillHideHook(std::optional<WindowWillHideHook> hook) {
296-
// Empty implementation
332+
pimpl_->will_hide_hook_ = std::move(hook);
297333
}
298334

299335
void WindowManager::InvokeWillShowHook(WindowId id) {
300-
// Empty implementation
336+
if (pimpl_->will_show_hook_) {
337+
(*pimpl_->will_show_hook_)(id);
338+
}
301339
}
302340

303341
void WindowManager::InvokeWillHideHook(WindowId id) {
304-
// Empty implementation
342+
if (pimpl_->will_hide_hook_) {
343+
(*pimpl_->will_hide_hook_)(id);
344+
}
305345
}
306346

307347
} // namespace nativeapi

src/platform/windows/window_manager_windows.cpp

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,18 @@ namespace nativeapi {
1212
// Custom window procedure to handle window messages
1313
static LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
1414
switch (uMsg) {
15+
case WM_SHOWWINDOW: {
16+
// wParam: TRUE if the window is being shown, FALSE if hidden
17+
auto& manager = WindowManager::GetInstance();
18+
Window temp_window(hwnd);
19+
WindowId window_id = temp_window.GetId();
20+
if (wParam) {
21+
manager.InvokeWillShowHook(window_id);
22+
} else {
23+
manager.InvokeWillHideHook(window_id);
24+
}
25+
return DefWindowProc(hwnd, uMsg, wParam, lParam);
26+
}
1527
case WM_CLOSE:
1628
// User clicked the close button
1729
DestroyWindow(hwnd);
@@ -85,6 +97,11 @@ class WindowManager::Impl {
8597

8698
private:
8799
WindowManager* manager_;
100+
// Optional pre-show/hide hooks
101+
std::optional<WindowManager::WindowWillShowHook> will_show_hook_;
102+
std::optional<WindowManager::WindowWillHideHook> will_hide_hook_;
103+
104+
friend class WindowManager;
88105
};
89106

90107
WindowManager::WindowManager() : pimpl_(std::make_unique<Impl>(this)) {
@@ -218,19 +235,23 @@ std::shared_ptr<Window> WindowManager::GetCurrent() {
218235
}
219236

220237
void WindowManager::SetWillShowHook(std::optional<WindowWillShowHook> hook) {
221-
// Empty implementation
238+
pimpl_->will_show_hook_ = std::move(hook);
222239
}
223240

224241
void WindowManager::SetWillHideHook(std::optional<WindowWillHideHook> hook) {
225-
// Empty implementation
242+
pimpl_->will_hide_hook_ = std::move(hook);
226243
}
227244

228245
void WindowManager::InvokeWillShowHook(WindowId id) {
229-
// Empty implementation
246+
if (pimpl_->will_show_hook_) {
247+
(*pimpl_->will_show_hook_)(id);
248+
}
230249
}
231250

232251
void WindowManager::InvokeWillHideHook(WindowId id) {
233-
// Empty implementation
252+
if (pimpl_->will_hide_hook_) {
253+
(*pimpl_->will_hide_hook_)(id);
254+
}
234255
}
235256

236257
} // namespace nativeapi

0 commit comments

Comments
 (0)