Skip to content

Commit 3be4d55

Browse files
committed
Add title bar style API to window abstraction
Introduces TitleBarStyle enum and related methods to set and get window title bar style across platforms. Updates C API to expose title bar style control, adds implementation for Linux, macOS, and Windows, and stubs for Android, iOS, and OHOS. Refactors window creation in C API and updates examples to demonstrate title bar toggling via context menu.
1 parent dda7f22 commit 3be4d55

File tree

18 files changed

+379
-51
lines changed

18 files changed

+379
-51
lines changed

examples/application_c_example/main.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ int main() {
4848
}
4949

5050
// Create a simple window with default settings
51-
native_window_t window = native_window_manager_create();
51+
native_window_t window = native_window_create();
5252
if (!window) {
5353
fprintf(stderr, "Failed to create window\n");
5454
return 1;

examples/window_c_example/main.c

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,19 @@ void on_hide_window_clicked(const void* event, void* user_data) {
5858
}
5959
}
6060

61+
void on_toggle_title_bar_clicked(const void* event, void* user_data) {
62+
printf("Toggle Title Bar clicked from context menu\n");
63+
if (g_window) {
64+
native_title_bar_style_t current_style = native_window_get_title_bar_style(g_window);
65+
native_title_bar_style_t new_style = (current_style == NATIVE_TITLE_BAR_STYLE_HIDDEN)
66+
? NATIVE_TITLE_BAR_STYLE_NORMAL
67+
: NATIVE_TITLE_BAR_STYLE_HIDDEN;
68+
native_window_set_title_bar_style(g_window, new_style);
69+
printf("Title bar style changed to: %s\n",
70+
(new_style == NATIVE_TITLE_BAR_STYLE_HIDDEN) ? "Hidden" : "Normal");
71+
}
72+
}
73+
6174
void on_about_clicked(const void* event, void* user_data) {
6275
printf("About clicked from context menu\n");
6376
printf("Window Example v1.0 - Native API Demo\n");
@@ -187,6 +200,13 @@ native_menu_t create_context_menu(void) {
187200
on_hide_window_clicked, NULL);
188201
native_menu_add_item(context_menu, hide_window_item);
189202

203+
// Add Toggle Title Bar item
204+
native_menu_item_t toggle_title_bar_item =
205+
native_menu_item_create("Toggle Title Bar", NATIVE_MENU_ITEM_TYPE_NORMAL);
206+
native_menu_item_add_listener(toggle_title_bar_item, NATIVE_MENU_ITEM_EVENT_CLICKED,
207+
on_toggle_title_bar_clicked, NULL);
208+
native_menu_add_item(context_menu, toggle_title_bar_item);
209+
190210
// Add separator
191211
native_menu_add_separator(context_menu);
192212

@@ -309,7 +329,7 @@ native_menu_t create_context_menu(void) {
309329

310330
int main() {
311331
// Create a new window with default settings
312-
g_window = native_window_manager_create();
332+
g_window = native_window_create();
313333

314334
// Configure the window
315335
native_window_set_title(g_window, "Window Example");
@@ -381,6 +401,9 @@ int main() {
381401
// Set the context menu to the tray icon
382402
native_tray_icon_set_context_menu(g_tray_icon, g_context_menu);
383403

404+
// Set context menu to trigger on left click
405+
native_tray_icon_set_context_menu_trigger(g_tray_icon, NATIVE_CONTEXT_MENU_TRIGGER_CLICKED);
406+
384407
// Set up event listeners
385408
native_tray_icon_add_listener(g_tray_icon, NATIVE_TRAY_ICON_EVENT_CLICKED, on_tray_icon_clicked,
386409
NULL);

examples/window_example/main.cpp

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -281,14 +281,13 @@ int main() {
281281

282282
// Add exit item
283283
auto exit_item = std::make_shared<MenuItem>("Exit", MenuItemType::Normal);
284-
exit_item->AddListener<MenuItemClickedEvent>(
285-
[window_ptr](const MenuItemClickedEvent& event) {
286-
std::cout << "Exit clicked from context menu" << std::endl;
287-
// Close the window to trigger app exit
288-
if (window_ptr) {
289-
window_ptr->Hide();
290-
}
291-
});
284+
exit_item->AddListener<MenuItemClickedEvent>([window_ptr](const MenuItemClickedEvent& event) {
285+
std::cout << "Exit clicked from context menu" << std::endl;
286+
// Close the window to trigger app exit
287+
if (window_ptr) {
288+
window_ptr->Hide();
289+
}
290+
});
292291
context_menu->AddItem(exit_item);
293292

294293
// Set the context menu to the tray icon

src/capi/positioning_strategy_c.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ native_positioning_strategy_t native_positioning_strategy_relative(const native_
7373
*
7474
* @example
7575
* ```c
76-
* native_window_t window = native_window_manager_create(&options);
76+
* native_window_t window = native_window_create();
7777
* native_point_t offset = {0, 10};
7878
* native_positioning_strategy_t strategy = native_positioning_strategy_relative_to_window(window,
7979
* &offset); native_menu_open(menu, strategy); native_positioning_strategy_free(strategy);

src/capi/window_c.cpp

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,81 @@
11
#include "window_c.h"
22
#include <cstring>
3+
#include <memory>
4+
#include <mutex>
5+
#include <unordered_map>
36
#include "../window.h"
47
#include "string_utils_c.h"
58

69
using namespace nativeapi;
710

11+
// Internal registry to manage window lifetimes for C API
12+
// This keeps shared_ptr alive while C code holds the handle
13+
namespace {
14+
std::mutex g_windows_mutex;
15+
std::unordered_map<WindowId, std::shared_ptr<Window>> g_windows;
16+
} // namespace
17+
18+
// Window creation and destruction
19+
FFI_PLUGIN_EXPORT
20+
native_window_t native_window_create(void) {
21+
try {
22+
// Create window with default settings
23+
auto window = std::make_shared<Window>();
24+
25+
// Store in internal registry to keep it alive
26+
{
27+
std::lock_guard<std::mutex> lock(g_windows_mutex);
28+
g_windows[window->GetId()] = window;
29+
}
30+
31+
// Return raw pointer (internal registry holds the shared_ptr)
32+
return static_cast<void*>(window.get());
33+
} catch (...) {
34+
return nullptr;
35+
}
36+
}
37+
38+
FFI_PLUGIN_EXPORT
39+
native_window_t native_window_create_from_native(void* native_window) {
40+
if (!native_window)
41+
return nullptr;
42+
43+
try {
44+
// Wrap existing native window
45+
auto window = std::make_shared<Window>(native_window);
46+
47+
// Store in internal registry to keep it alive
48+
{
49+
std::lock_guard<std::mutex> lock(g_windows_mutex);
50+
g_windows[window->GetId()] = window;
51+
}
52+
53+
// Return raw pointer (internal registry holds the shared_ptr)
54+
return static_cast<void*>(window.get());
55+
} catch (...) {
56+
return nullptr;
57+
}
58+
}
59+
60+
FFI_PLUGIN_EXPORT
61+
void native_window_destroy(native_window_t window) {
62+
if (!window)
63+
return;
64+
65+
try {
66+
auto* win = static_cast<nativeapi::Window*>(window);
67+
WindowId window_id = win->GetId();
68+
69+
// Remove from internal registry (this will destroy it if no other references exist)
70+
{
71+
std::lock_guard<std::mutex> lock(g_windows_mutex);
72+
g_windows.erase(window_id);
73+
}
74+
} catch (...) {
75+
// Silently fail
76+
}
77+
}
78+
879
// Window basic operations
980
FFI_PLUGIN_EXPORT
1081
native_window_id_t native_window_get_id(native_window_t window) {
@@ -443,6 +514,36 @@ char* native_window_get_title(native_window_t window) {
443514
}
444515
}
445516

517+
FFI_PLUGIN_EXPORT
518+
void native_window_set_title_bar_style(native_window_t window, native_title_bar_style_t style) {
519+
if (!window)
520+
return;
521+
522+
try {
523+
auto* win = static_cast<nativeapi::Window*>(window);
524+
TitleBarStyle cpp_style =
525+
(style == NATIVE_TITLE_BAR_STYLE_HIDDEN) ? TitleBarStyle::Hidden : TitleBarStyle::Normal;
526+
win->SetTitleBarStyle(cpp_style);
527+
} catch (...) {
528+
// Silently fail
529+
}
530+
}
531+
532+
FFI_PLUGIN_EXPORT
533+
native_title_bar_style_t native_window_get_title_bar_style(native_window_t window) {
534+
if (!window)
535+
return NATIVE_TITLE_BAR_STYLE_NORMAL;
536+
537+
try {
538+
auto* win = static_cast<nativeapi::Window*>(window);
539+
TitleBarStyle cpp_style = win->GetTitleBarStyle();
540+
return (cpp_style == TitleBarStyle::Hidden) ? NATIVE_TITLE_BAR_STYLE_HIDDEN
541+
: NATIVE_TITLE_BAR_STYLE_NORMAL;
542+
} catch (...) {
543+
return NATIVE_TITLE_BAR_STYLE_NORMAL;
544+
}
545+
}
546+
446547
FFI_PLUGIN_EXPORT
447548
void native_window_set_has_shadow(native_window_t window, bool has_shadow) {
448549
if (!window)

src/capi/window_c.h

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,24 @@ typedef struct {
3333
long count;
3434
} native_window_list_t;
3535

36+
/**
37+
* Title bar style enumeration
38+
*/
39+
typedef enum {
40+
NATIVE_TITLE_BAR_STYLE_NORMAL = 0,
41+
NATIVE_TITLE_BAR_STYLE_HIDDEN = 1
42+
} native_title_bar_style_t;
43+
44+
// Window creation and destruction
45+
FFI_PLUGIN_EXPORT
46+
native_window_t native_window_create(void);
47+
48+
FFI_PLUGIN_EXPORT
49+
native_window_t native_window_create_from_native(void* native_window);
50+
51+
FFI_PLUGIN_EXPORT
52+
void native_window_destroy(native_window_t window);
53+
3654
// Window basic operations
3755
FFI_PLUGIN_EXPORT
3856
native_window_id_t native_window_get_id(native_window_t window);
@@ -178,6 +196,12 @@ bool native_window_set_title(native_window_t window, const char* title);
178196
FFI_PLUGIN_EXPORT
179197
char* native_window_get_title(native_window_t window);
180198

199+
FFI_PLUGIN_EXPORT
200+
void native_window_set_title_bar_style(native_window_t window, native_title_bar_style_t style);
201+
202+
FFI_PLUGIN_EXPORT
203+
native_title_bar_style_t native_window_get_title_bar_style(native_window_t window);
204+
181205
FFI_PLUGIN_EXPORT
182206
void native_window_set_has_shadow(native_window_t window, bool has_shadow);
183207

src/capi/window_manager_c.cpp

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -113,17 +113,6 @@ static native_window_will_hide_callback_t g_will_hide_cb = nullptr;
113113
static void* g_will_hide_ud = nullptr;
114114

115115
// Window manager operations
116-
FFI_PLUGIN_EXPORT
117-
native_window_t native_window_manager_create(void) {
118-
try {
119-
// Create window with default settings (automatically registered)
120-
auto window = std::make_shared<Window>();
121-
return CreateNativeWindowHandle(window);
122-
} catch (...) {
123-
return nullptr;
124-
}
125-
}
126-
127116
FFI_PLUGIN_EXPORT
128117
native_window_t native_window_manager_get(native_window_id_t window_id) {
129118
try {

src/capi/window_manager_c.h

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -53,13 +53,6 @@ typedef void (*native_window_event_callback_t)(const native_window_event_t* even
5353
* Window manager singleton operations
5454
*/
5555

56-
/**
57-
* Create a new window with default settings
58-
* @return Window handle, or NULL if creation failed
59-
*/
60-
FFI_PLUGIN_EXPORT
61-
native_window_t native_window_manager_create(void);
62-
6356
/**
6457
* Get a window by its ID
6558
* @param window_id The window ID

src/platform/android/window_android.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,14 @@ std::string Window::GetTitle() const {
292292
return "";
293293
}
294294

295+
void Window::SetTitleBarStyle(TitleBarStyle style) {
296+
ALOGW("SetTitleBarStyle not supported on Android (use system UI visibility flags)");
297+
}
298+
299+
TitleBarStyle Window::GetTitleBarStyle() const {
300+
return TitleBarStyle::Normal;
301+
}
302+
295303
void Window::SetHasShadow(bool has_shadow) {
296304
ALOGW("SetHasShadow not supported on Android");
297305
}

src/platform/ios/window_ios.mm

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -331,6 +331,16 @@
331331
return "";
332332
}
333333

334+
void Window::SetTitleBarStyle(TitleBarStyle style) {
335+
// iOS doesn't have traditional title bars
336+
// Use UIViewController.prefersStatusBarHidden or navigation bar appearance instead
337+
NSLog(@"SetTitleBarStyle not applicable on iOS (use status bar or navigation bar APIs)");
338+
}
339+
340+
TitleBarStyle Window::GetTitleBarStyle() const {
341+
return TitleBarStyle::Normal;
342+
}
343+
334344
void Window::SetHasShadow(bool has_shadow) {
335345
// iOS manages shadow automatically
336346
}

0 commit comments

Comments
 (0)