Skip to content

Commit f3627fb

Browse files
committed
Sync with core 151f89127: tray icon content views
Core gains TrayIcon::SetContentView, a custom native view in place of the icon and title on macOS: the view fills the whole status item, padding included, and the item draws no highlight behind it. Two core examples show it: tray_view_example (a menu bar item drawn by native views) and tray_stats_example (a system monitor laid out in the menu bar). Regenerated C ABI and every binding (Rust, Dart, C#, JS, Python) for the new call; specs/view.md notes the tray as a host of views.
1 parent df3c836 commit f3627fb

13 files changed

Lines changed: 197 additions & 55 deletions

File tree

‎bindings/csharp/src/CNativeAPI/generated/TrayIcon.cs‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,9 @@ public static partial class Interop
110110
[DllImport(Libraries.NativeApi, CallingConvention = CallingConvention.Cdecl)]
111111
public static extern ulong native_tray_icon_create_with_tray(IntPtr tray);
112112

113+
[DllImport(Libraries.NativeApi, CallingConvention = CallingConvention.Cdecl)]
114+
public static extern ulong native_tray_icon_get_content_view(ulong self);
115+
113116
[DllImport(Libraries.NativeApi, CallingConvention = CallingConvention.Cdecl)]
114117
public static extern ulong native_tray_icon_get_context_menu(ulong self);
115118

@@ -122,6 +125,9 @@ public static partial class Interop
122125
[DllImport(Libraries.NativeApi, CallingConvention = CallingConvention.Cdecl)]
123126
public static extern void native_tray_icon_list_release(ref native_tray_icon_list_t list);
124127

128+
[DllImport(Libraries.NativeApi, CallingConvention = CallingConvention.Cdecl)]
129+
public static extern void native_tray_icon_set_content_view(ulong self, ulong view);
130+
125131
[DllImport(Libraries.NativeApi, CallingConvention = CallingConvention.Cdecl)]
126132
public static extern void native_tray_icon_set_context_menu(ulong self, ulong menu);
127133

‎bindings/csharp/src/NativeAPI/TrayIcon.cs‎

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,20 @@ public void SetTooltip(string? tooltip)
172172
return Interop.ConsumeString(rawResult);
173173
}
174174

175+
public void SetContentView(View? view)
176+
{
177+
Interop.native_tray_icon_set_content_view(NativeHandle, view?.NativeHandle ?? 0);
178+
}
179+
180+
public View? ContentView
181+
{
182+
get
183+
{
184+
var rawResult = Interop.native_tray_icon_get_content_view(NativeHandle);
185+
return rawResult == 0 ? null : new View(rawResult);
186+
}
187+
}
188+
175189
public void SetContextMenu(Menu? menu)
176190
{
177191
Interop.native_tray_icon_set_context_menu(NativeHandle, menu?.NativeHandle ?? 0);

‎bindings/dart/cnativeapi/lib/src/bindings_generated.dart‎

Lines changed: 66 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1883,6 +1883,10 @@ external void native_tray_icon_free(int tray_icon);
18831883
@ffi.Native<native_rectangle_t Function(native_tray_icon_t)>()
18841884
external native_rectangle_t native_tray_icon_get_bounds(int tray_icon);
18851885

1886+
/// Caller owns the returned handle; release it with native_view_free().
1887+
@ffi.Native<native_view_t Function(native_tray_icon_t)>()
1888+
external int native_tray_icon_get_content_view(int tray_icon);
1889+
18861890
/// Caller owns the returned handle; release it with native_menu_free().
18871891
@ffi.Native<native_menu_t$1 Function(native_tray_icon_t)>()
18881892
external int native_tray_icon_get_context_menu(int tray_icon);
@@ -1962,6 +1966,9 @@ external bool native_tray_icon_open_context_menu(int tray_icon);
19621966
@ffi.Native<ffi.Bool Function(native_tray_icon_t, native_listener_id_t)>()
19631967
external bool native_tray_icon_remove_listener(int tray_icon, int listener_id);
19641968

1969+
@ffi.Native<ffi.Void Function(native_tray_icon_t, native_view_t)>()
1970+
external void native_tray_icon_set_content_view(int tray_icon, int view);
1971+
19651972
@ffi.Native<ffi.Void Function(native_tray_icon_t, native_menu_t$1)>()
19661973
external void native_tray_icon_set_context_menu(int tray_icon, int menu);
19671974

@@ -2050,7 +2057,7 @@ external native_url_open_result_t native_url_opener_open(
20502057
/// @return the listener id, or NATIVE_INVALID_LISTENER_ID on failure.
20512058
@ffi.Native<
20522059
native_listener_id_t Function(
2053-
native_view_t,
2060+
native_view_t$1,
20542061
native_view_event_callback_t,
20552062
ffi.Pointer<ffi.Void>,
20562063
native_release_user_data_t,
@@ -2063,52 +2070,52 @@ external int native_view_add_listener(
20632070
native_release_user_data_t release_user_data,
20642071
);
20652072

2066-
@ffi.Native<ffi.Void Function(native_view_t, native_view_t)>()
2073+
@ffi.Native<ffi.Void Function(native_view_t$1, native_view_t$1)>()
20672074
external void native_view_add_subview(int view, int subview);
20682075

2069-
@ffi.Native<ffi.Void Function(native_view_t)>()
2076+
@ffi.Native<ffi.Void Function(native_view_t$1)>()
20702077
external void native_view_blur(int view);
20712078

2072-
@ffi.Native<ffi.Void Function(native_view_t)>()
2079+
@ffi.Native<ffi.Void Function(native_view_t$1)>()
20732080
external void native_view_clear_subviews(int view);
20742081

20752082
/// Creates a View instance; release it with native_view_free().
2076-
@ffi.Native<native_view_t Function()>()
2083+
@ffi.Native<native_view_t$1 Function()>()
20772084
external int native_view_create();
20782085

20792086
/// Creates a View instance; release it with native_view_free().
2080-
@ffi.Native<native_view_t Function(ffi.Pointer<ffi.Void>)>()
2087+
@ffi.Native<native_view_t$1 Function(ffi.Pointer<ffi.Void>)>()
20812088
external int native_view_create_with_native_view(
20822089
ffi.Pointer<ffi.Void> native_view,
20832090
);
20842091

2085-
@ffi.Native<ffi.Void Function(native_view_t)>()
2092+
@ffi.Native<ffi.Void Function(native_view_t$1)>()
20862093
external void native_view_focus(int view);
20872094

20882095
/// Releases the caller's reference. Safe to call with an invalid or
20892096
/// already-released handle.
2090-
@ffi.Native<ffi.Void Function(native_view_t)>()
2097+
@ffi.Native<ffi.Void Function(native_view_t$1)>()
20912098
external void native_view_free(int view);
20922099

2093-
@ffi.Native<ffi.UnsignedInt Function(native_view_t)>(
2100+
@ffi.Native<ffi.UnsignedInt Function(native_view_t$1)>(
20942101
symbol: 'native_view_get_alignment',
20952102
)
20962103
external int _native_view_get_alignment(int view);
20972104

2098-
native_view_alignment_t native_view_get_alignment(Dartnative_view_t view) {
2105+
native_view_alignment_t native_view_get_alignment(Dartnative_view_t$1 view) {
20992106
return native_view_alignment_t.fromValue(_native_view_get_alignment(view));
21002107
}
21012108

2102-
@ffi.Native<ffi.UnsignedInt Function(native_view_t)>(
2109+
@ffi.Native<ffi.UnsignedInt Function(native_view_t$1)>(
21032110
symbol: 'native_view_get_backend',
21042111
)
21052112
external int _native_view_get_backend(int view);
21062113

2107-
native_view_backend_t native_view_get_backend(Dartnative_view_t view) {
2114+
native_view_backend_t native_view_get_backend(Dartnative_view_t$1 view) {
21082115
return native_view_backend_t.fromValue(_native_view_get_backend(view));
21092116
}
21102117

2111-
@ffi.Native<native_color_t Function(native_view_t)>()
2118+
@ffi.Native<native_color_t Function(native_view_t$1)>()
21122119
external native_color_t native_view_get_background_color(int view);
21132120

21142121
@ffi.Native<ffi.UnsignedInt Function()>(
@@ -2120,63 +2127,65 @@ native_view_backend_t native_view_get_default_backend() {
21202127
return native_view_backend_t.fromValue(_native_view_get_default_backend());
21212128
}
21222129

2123-
@ffi.Native<ffi.Double Function(native_view_t)>()
2130+
@ffi.Native<ffi.Double Function(native_view_t$1)>()
21242131
external double native_view_get_flex(int view);
21252132

2126-
@ffi.Native<native_rectangle_t Function(native_view_t)>()
2133+
@ffi.Native<native_rectangle_t Function(native_view_t$1)>()
21272134
external native_rectangle_t native_view_get_frame(int view);
21282135

2129-
@ffi.Native<native_view_id_t Function(native_view_t)>()
2136+
@ffi.Native<native_view_id_t Function(native_view_t$1)>()
21302137
external int native_view_get_id(int view);
21312138

2132-
@ffi.Native<native_size_t Function(native_view_t)>()
2139+
@ffi.Native<native_size_t Function(native_view_t$1)>()
21332140
external native_size_t native_view_get_intrinsic_size(int view);
21342141

2135-
@ffi.Native<ffi.UnsignedInt Function(native_view_t)>(
2142+
@ffi.Native<ffi.UnsignedInt Function(native_view_t$1)>(
21362143
symbol: 'native_view_get_layout',
21372144
)
21382145
external int _native_view_get_layout(int view);
21392146

2140-
native_view_layout_t native_view_get_layout(Dartnative_view_t view) {
2147+
native_view_layout_t native_view_get_layout(Dartnative_view_t$1 view) {
21412148
return native_view_layout_t.fromValue(_native_view_get_layout(view));
21422149
}
21432150

21442151
/// Platform-specific native object (NSScreen*, HMONITOR, ...).
2145-
@ffi.Native<ffi.Pointer<ffi.Void> Function(native_view_t)>()
2152+
@ffi.Native<ffi.Pointer<ffi.Void> Function(native_view_t$1)>()
21462153
external ffi.Pointer<ffi.Void> native_view_get_native_object(int view);
21472154

2148-
@ffi.Native<native_edge_insets_t Function(native_view_t)>()
2155+
@ffi.Native<native_edge_insets_t Function(native_view_t$1)>()
21492156
external native_edge_insets_t native_view_get_padding(int view);
21502157

21512158
/// Caller owns the returned handle; release it with native_view_free().
2152-
@ffi.Native<native_view_t Function(native_view_t)>()
2159+
@ffi.Native<native_view_t$1 Function(native_view_t$1)>()
21532160
external int native_view_get_parent(int view);
21542161

2155-
@ffi.Native<native_size_t Function(native_view_t)>()
2162+
@ffi.Native<native_size_t Function(native_view_t$1)>()
21562163
external native_size_t native_view_get_preferred_size(int view);
21572164

2158-
@ffi.Native<ffi.Double Function(native_view_t)>()
2165+
@ffi.Native<ffi.Double Function(native_view_t$1)>()
21592166
external double native_view_get_spacing(int view);
21602167

21612168
/// Caller owns the returned handle; release it with native_view_free().
2162-
@ffi.Native<native_view_t Function(native_view_t, ffi.UnsignedLong)>()
2169+
@ffi.Native<native_view_t$1 Function(native_view_t$1, ffi.UnsignedLong)>()
21632170
external int native_view_get_subview_at(int view, int index);
21642171

2165-
@ffi.Native<ffi.UnsignedLong Function(native_view_t)>()
2172+
@ffi.Native<ffi.UnsignedLong Function(native_view_t$1)>()
21662173
external int native_view_get_subview_count(int view);
21672174

2168-
@ffi.Native<native_view_list_t Function(native_view_t)>()
2175+
@ffi.Native<native_view_list_t Function(native_view_t$1)>()
21692176
external native_view_list_t native_view_get_subviews(int view);
21702177

21712178
/// Caller owns the returned string; free it with free_c_str().
2172-
@ffi.Native<ffi.Pointer<ffi.Char> Function(native_view_t)>()
2179+
@ffi.Native<ffi.Pointer<ffi.Char> Function(native_view_t$1)>()
21732180
external ffi.Pointer<ffi.Char> native_view_get_tooltip(int view);
21742181

21752182
/// Caller owns the returned handle; release it with native_window_free().
2176-
@ffi.Native<native_window_t Function(native_view_t)>()
2183+
@ffi.Native<native_window_t Function(native_view_t$1)>()
21772184
external int native_view_get_window(int view);
21782185

2179-
@ffi.Native<ffi.Void Function(native_view_t, ffi.UnsignedLong, native_view_t)>()
2186+
@ffi.Native<
2187+
ffi.Void Function(native_view_t$1, ffi.UnsignedLong, native_view_t$1)
2188+
>()
21802189
external void native_view_insert_subview(int view, int index, int subview);
21812190

21822191
@ffi.Native<ffi.Bool Function(ffi.UnsignedInt)>(
@@ -2188,16 +2197,16 @@ bool native_view_is_backend_supported(native_view_backend_t backend) {
21882197
return _native_view_is_backend_supported(backend.value);
21892198
}
21902199

2191-
@ffi.Native<ffi.Bool Function(native_view_t)>()
2200+
@ffi.Native<ffi.Bool Function(native_view_t$1)>()
21922201
external bool native_view_is_enabled(int view);
21932202

2194-
@ffi.Native<ffi.Bool Function(native_view_t)>()
2203+
@ffi.Native<ffi.Bool Function(native_view_t$1)>()
21952204
external bool native_view_is_focused(int view);
21962205

21972206
@ffi.Native<ffi.Bool Function()>()
21982207
external bool native_view_is_supported();
21992208

2200-
@ffi.Native<ffi.Bool Function(native_view_t)>()
2209+
@ffi.Native<ffi.Bool Function(native_view_t$1)>()
22012210
external bool native_view_is_visible(int view);
22022211

22032212
/// Frees the array and releases every handle it contains.
@@ -2209,28 +2218,28 @@ external void native_view_list_free(ffi.Pointer<native_view_list_t> list);
22092218
external void native_view_list_release(ffi.Pointer<native_view_list_t> list);
22102219

22112220
/// Unregisters a listener. Returns false if unknown.
2212-
@ffi.Native<ffi.Bool Function(native_view_t, native_listener_id_t)>()
2221+
@ffi.Native<ffi.Bool Function(native_view_t$1, native_listener_id_t)>()
22132222
external bool native_view_remove_listener(int view, int listener_id);
22142223

2215-
@ffi.Native<ffi.Bool Function(native_view_t, native_view_t)>()
2224+
@ffi.Native<ffi.Bool Function(native_view_t$1, native_view_t$1)>()
22162225
external bool native_view_remove_subview(int view, int subview);
22172226

2218-
@ffi.Native<ffi.Bool Function(native_view_t, ffi.UnsignedLong)>()
2227+
@ffi.Native<ffi.Bool Function(native_view_t$1, ffi.UnsignedLong)>()
22192228
external bool native_view_remove_subview_at(int view, int index);
22202229

2221-
@ffi.Native<ffi.Void Function(native_view_t, ffi.UnsignedInt)>(
2230+
@ffi.Native<ffi.Void Function(native_view_t$1, ffi.UnsignedInt)>(
22222231
symbol: 'native_view_set_alignment',
22232232
)
22242233
external void _native_view_set_alignment(int view, int alignment);
22252234

22262235
void native_view_set_alignment(
2227-
Dartnative_view_t view,
2236+
Dartnative_view_t$1 view,
22282237
native_view_alignment_t alignment,
22292238
) {
22302239
return _native_view_set_alignment(view, alignment.value);
22312240
}
22322241

2233-
@ffi.Native<ffi.Void Function(native_view_t, native_color_t)>()
2242+
@ffi.Native<ffi.Void Function(native_view_t$1, native_color_t)>()
22342243
external void native_view_set_background_color(int view, native_color_t color);
22352244

22362245
@ffi.Native<ffi.Bool Function(ffi.UnsignedInt)>(
@@ -2242,40 +2251,40 @@ bool native_view_set_default_backend(native_view_backend_t backend) {
22422251
return _native_view_set_default_backend(backend.value);
22432252
}
22442253

2245-
@ffi.Native<ffi.Void Function(native_view_t, ffi.Bool)>()
2254+
@ffi.Native<ffi.Void Function(native_view_t$1, ffi.Bool)>()
22462255
external void native_view_set_enabled(int view, bool is_enabled);
22472256

2248-
@ffi.Native<ffi.Void Function(native_view_t, ffi.Double)>()
2257+
@ffi.Native<ffi.Void Function(native_view_t$1, ffi.Double)>()
22492258
external void native_view_set_flex(int view, double flex);
22502259

2251-
@ffi.Native<ffi.Void Function(native_view_t, native_rectangle_t)>()
2260+
@ffi.Native<ffi.Void Function(native_view_t$1, native_rectangle_t)>()
22522261
external void native_view_set_frame(int view, native_rectangle_t frame);
22532262

2254-
@ffi.Native<ffi.Void Function(native_view_t, ffi.UnsignedInt)>(
2263+
@ffi.Native<ffi.Void Function(native_view_t$1, ffi.UnsignedInt)>(
22552264
symbol: 'native_view_set_layout',
22562265
)
22572266
external void _native_view_set_layout(int view, int layout);
22582267

22592268
void native_view_set_layout(
2260-
Dartnative_view_t view,
2269+
Dartnative_view_t$1 view,
22612270
native_view_layout_t layout,
22622271
) {
22632272
return _native_view_set_layout(view, layout.value);
22642273
}
22652274

2266-
@ffi.Native<ffi.Void Function(native_view_t, native_edge_insets_t)>()
2275+
@ffi.Native<ffi.Void Function(native_view_t$1, native_edge_insets_t)>()
22672276
external void native_view_set_padding(int view, native_edge_insets_t padding);
22682277

2269-
@ffi.Native<ffi.Void Function(native_view_t, native_size_t)>()
2278+
@ffi.Native<ffi.Void Function(native_view_t$1, native_size_t)>()
22702279
external void native_view_set_preferred_size(int view, native_size_t size);
22712280

2272-
@ffi.Native<ffi.Void Function(native_view_t, ffi.Double)>()
2281+
@ffi.Native<ffi.Void Function(native_view_t$1, ffi.Double)>()
22732282
external void native_view_set_spacing(int view, double spacing);
22742283

2275-
@ffi.Native<ffi.Void Function(native_view_t, ffi.Pointer<ffi.Char>)>()
2284+
@ffi.Native<ffi.Void Function(native_view_t$1, ffi.Pointer<ffi.Char>)>()
22762285
external void native_view_set_tooltip(int view, ffi.Pointer<ffi.Char> tooltip);
22772286

2278-
@ffi.Native<ffi.Void Function(native_view_t, ffi.Bool)>()
2287+
@ffi.Native<ffi.Void Function(native_view_t$1, ffi.Bool)>()
22792288
external void native_view_set_visible(int view, bool is_visible);
22802289

22812290
@ffi.Native<ffi.Void Function(native_window_t)>()
@@ -2380,7 +2389,7 @@ external native_rectangle_t native_window_get_content_bounds(int window);
23802389
external native_size_t native_window_get_content_size(int window);
23812390

23822391
/// Caller owns the returned handle; release it with native_view_free().
2383-
@ffi.Native<native_view_t Function(native_window_t)>()
2392+
@ffi.Native<native_view_t$1 Function(native_window_t)>()
23842393
external int native_window_get_content_view(int window);
23852394

23862395
/// Caller owns the returned handle; release it with native_window_shadow_free().
@@ -4681,28 +4690,31 @@ enum native_view_layout_t {
46814690

46824691
/// Owning list of View handles.
46834692
final class native_view_list_t extends ffi.Struct {
4684-
external ffi.Pointer<native_view_t> views;
4693+
external ffi.Pointer<native_view_t$1> views;
46854694

46864695
@ffi.Long()
46874696
external int count;
46884697

46894698
static ffi.Pointer<native_view_list_t> $allocate(
46904699
ffi.Allocator $allocator, {
4691-
required ffi.Pointer<native_view_t> views,
4700+
required ffi.Pointer<native_view_t$1> views,
46924701
required int count,
46934702
}) => $allocator<native_view_list_t>()
46944703
..ref.views = views
46954704
..ref.count = count;
46964705
}
46974706

4707+
typedef native_view_t = ffi.Uint64;
4708+
typedef Dartnative_view_t = int;
4709+
46984710
/// Opaque View handle.
46994711
///
47004712
/// A generational index into the library's handle table, NOT a pointer:
47014713
/// never dereference it, and compare it against NATIVE_INVALID_VIEW rather than NULL.
47024714
/// Releasing a handle invalidates it; later calls fail safely instead of
47034715
/// touching freed memory.
4704-
typedef native_view_t = ffi.Uint64;
4705-
typedef Dartnative_view_t = int;
4716+
typedef native_view_t$1 = ffi.Uint64;
4717+
typedef Dartnative_view_t$1 = int;
47064718

47074719
enum native_visual_effect_t {
47084720
NATIVE_VISUAL_EFFECT_NONE(0),

‎bindings/dart/nativeapi/CHANGELOG.md‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
## Unreleased
22

3+
* `TrayIcon.contentView`: any `View` in place of the icon and title, on macOS.
4+
The menu bar item is as wide as the view (its `preferredSize`, or what a Row
5+
or Column needs) and follows it as it changes; clicks outside buttons and
6+
text fields still reach the tray icon's events. Recorded only on Windows and
7+
Linux.
38
* `runNativeApp()`: windows and native views from a plain Dart program, no
49
Flutter needed. The app runs in an isolate of its own on the platform's UI
510
thread, with Dart's timers, futures and streams working in between; on

0 commit comments

Comments
 (0)