From 0587a1d217688437718eb3978915558920a637fb Mon Sep 17 00:00:00 2001 From: bruvzg <7645683+bruvzg@users.noreply.github.com> Date: Sat, 16 Mar 2024 23:14:30 +0200 Subject: [PATCH] [StatusIndicator] Switch API to use Texture2D instead of Image, improve handling on macOS, add method to set native popup menu directly. --- doc/classes/DisplayServer.xml | 15 ++++- doc/classes/StatusIndicator.xml | 6 +- platform/macos/display_server_macos.h | 7 ++- platform/macos/display_server_macos.mm | 47 +++++++++++----- platform/macos/godot_status_item.h | 7 +-- platform/macos/godot_status_item.mm | 61 +++++++-------------- platform/macos/native_menu_macos.h | 2 + platform/macos/native_menu_macos.mm | 7 +++ platform/windows/display_server_windows.cpp | 40 +++++++++----- platform/windows/display_server_windows.h | 6 +- scene/main/status_indicator.cpp | 55 ++++++++++++++++++- scene/main/status_indicator.h | 10 +++- servers/display_server.cpp | 9 ++- servers/display_server.h | 5 +- 14 files changed, 188 insertions(+), 89 deletions(-) diff --git a/doc/classes/DisplayServer.xml b/doc/classes/DisplayServer.xml index ecb8438edbb..7c81a01610f 100644 --- a/doc/classes/DisplayServer.xml +++ b/doc/classes/DisplayServer.xml @@ -58,7 +58,7 @@ - + @@ -1178,11 +1178,22 @@ - + Sets the application status indicator icon. + + + + + + Sets the application status indicator native popup menu. + [b]Note:[/b] On macOS, the menu is activated by any mouse button. Its activation callback is [i]not[/i] triggered. + [b]Note:[/b] On Windows, the menu is activated by the right mouse button, selecting the status icon and pressing [kbd]Shift + F10[/kbd], or the applications key. The menu's activation callback for the other mouse buttons is still triggered. + [b]Note:[/b] Native popup is only supported if [NativeMenu] supports the [constant NativeMenu.FEATURE_POPUP_MENU] feature. + + diff --git a/doc/classes/StatusIndicator.xml b/doc/classes/StatusIndicator.xml index 6b015c3d15f..ca578d03e00 100644 --- a/doc/classes/StatusIndicator.xml +++ b/doc/classes/StatusIndicator.xml @@ -9,9 +9,13 @@ - + Status indicator icon. + + Status indicator native popup menu. If this is set, the [signal pressed] signal is not emitted. + [b]Note:[/b] Native popup is only supported if [NativeMenu] supports [constant NativeMenu.FEATURE_POPUP_MENU] feature. + Status indicator tooltip. diff --git a/platform/macos/display_server_macos.h b/platform/macos/display_server_macos.h index 09073a80309..1b0787c2d96 100644 --- a/platform/macos/display_server_macos.h +++ b/platform/macos/display_server_macos.h @@ -192,7 +192,7 @@ private: HashMap windows; struct IndicatorData { - id view; + id delegate; id item; }; @@ -430,9 +430,10 @@ public: virtual void set_native_icon(const String &p_filename) override; virtual void set_icon(const Ref &p_icon) override; - virtual IndicatorID create_status_indicator(const Ref &p_icon, const String &p_tooltip, const Callable &p_callback) override; - virtual void status_indicator_set_icon(IndicatorID p_id, const Ref &p_icon) override; + virtual IndicatorID create_status_indicator(const Ref &p_icon, const String &p_tooltip, const Callable &p_callback) override; + virtual void status_indicator_set_icon(IndicatorID p_id, const Ref &p_icon) override; virtual void status_indicator_set_tooltip(IndicatorID p_id, const String &p_tooltip) override; + virtual void status_indicator_set_menu(IndicatorID p_id, const RID &p_menu_rid) override; virtual void status_indicator_set_callback(IndicatorID p_id, const Callable &p_callback) override; virtual void delete_status_indicator(IndicatorID p_id) override; diff --git a/platform/macos/display_server_macos.mm b/platform/macos/display_server_macos.mm index c52ed00b3d9..23b5a03baa2 100644 --- a/platform/macos/display_server_macos.mm +++ b/platform/macos/display_server_macos.mm @@ -3131,10 +3131,11 @@ void DisplayServerMacOS::set_icon(const Ref &p_icon) { } } -DisplayServer::IndicatorID DisplayServerMacOS::create_status_indicator(const Ref &p_icon, const String &p_tooltip, const Callable &p_callback) { +DisplayServer::IndicatorID DisplayServerMacOS::create_status_indicator(const Ref &p_icon, const String &p_tooltip, const Callable &p_callback) { NSImage *nsimg = nullptr; if (p_icon.is_valid() && p_icon->get_width() > 0 && p_icon->get_height() > 0) { - Ref img = p_icon->duplicate(); + Ref img = p_icon->get_image(); + img = img->duplicate(); img->convert(Image::FORMAT_RGBA8); NSBitmapImageRep *imgrep = [[NSBitmapImageRep alloc] @@ -3172,13 +3173,18 @@ DisplayServer::IndicatorID DisplayServerMacOS::create_status_indicator(const Ref IndicatorData idat; - idat.item = [[NSStatusBar systemStatusBar] statusItemWithLength:NSSquareStatusItemLength]; - idat.view = [[GodotStatusItemView alloc] init]; + NSStatusItem *item = [[NSStatusBar systemStatusBar] statusItemWithLength:NSSquareStatusItemLength]; + idat.item = item; + idat.delegate = [[GodotStatusItemDelegate alloc] init]; + [idat.delegate setCallback:p_callback]; - [idat.view setToolTip:[NSString stringWithUTF8String:p_tooltip.utf8().get_data()]]; - [idat.view setImage:nsimg]; - [idat.view setCallback:p_callback]; - [idat.item setView:idat.view]; + item.button.image = nsimg; + item.button.imagePosition = NSImageOnly; + item.button.imageScaling = NSImageScaleProportionallyUpOrDown; + item.button.target = idat.delegate; + item.button.action = @selector(click:); + [item.button sendActionOn:(NSEventMaskLeftMouseDown | NSEventMaskRightMouseDown | NSEventMaskOtherMouseDown)]; + item.button.toolTip = [NSString stringWithUTF8String:p_tooltip.utf8().get_data()]; IndicatorID iid = indicator_id_counter++; indicators[iid] = idat; @@ -3186,12 +3192,13 @@ DisplayServer::IndicatorID DisplayServerMacOS::create_status_indicator(const Ref return iid; } -void DisplayServerMacOS::status_indicator_set_icon(IndicatorID p_id, const Ref &p_icon) { +void DisplayServerMacOS::status_indicator_set_icon(IndicatorID p_id, const Ref &p_icon) { ERR_FAIL_COND(!indicators.has(p_id)); NSImage *nsimg = nullptr; if (p_icon.is_valid() && p_icon->get_width() > 0 && p_icon->get_height() > 0) { - Ref img = p_icon->duplicate(); + Ref img = p_icon->get_image(); + img = img->duplicate(); img->convert(Image::FORMAT_RGBA8); NSBitmapImageRep *imgrep = [[NSBitmapImageRep alloc] @@ -3227,19 +3234,33 @@ void DisplayServerMacOS::status_indicator_set_icon(IndicatorID p_id, const Refhas_menu(p_menu_rid)) { + NSMenu *menu = native_menu->get_native_menu_handle(p_menu_rid); + item.menu = menu; + } else { + item.menu = nullptr; + } } void DisplayServerMacOS::status_indicator_set_callback(IndicatorID p_id, const Callable &p_callback) { ERR_FAIL_COND(!indicators.has(p_id)); - [indicators[p_id].view setCallback:p_callback]; + [indicators[p_id].delegate setCallback:p_callback]; } void DisplayServerMacOS::delete_status_indicator(IndicatorID p_id) { diff --git a/platform/macos/godot_status_item.h b/platform/macos/godot_status_item.h index 1827baa9bdb..5bc790956ef 100644 --- a/platform/macos/godot_status_item.h +++ b/platform/macos/godot_status_item.h @@ -37,13 +37,12 @@ #import #import -@interface GodotStatusItemView : NSView { - NSImage *image; +@interface GodotStatusItemDelegate : NSObject { Callable cb; } -- (void)processMouseEvent:(NSEvent *)event index:(MouseButton)index; -- (void)setImage:(NSImage *)image; +- (IBAction)click:(id)sender; + - (void)setCallback:(const Callable &)callback; @end diff --git a/platform/macos/godot_status_item.mm b/platform/macos/godot_status_item.mm index 71ed0a0f719..0990a16b2b3 100644 --- a/platform/macos/godot_status_item.mm +++ b/platform/macos/godot_status_item.mm @@ -32,30 +32,32 @@ #include "display_server_macos.h" -@implementation GodotStatusItemView +@implementation GodotStatusItemDelegate - (id)init { self = [super init]; - image = nullptr; return self; } -- (void)setImage:(NSImage *)newImage { - image = newImage; - [self setNeedsDisplayInRect:self.frame]; -} - -- (void)setCallback:(const Callable &)callback { - cb = callback; -} - -- (void)drawRect:(NSRect)rect { - if (image) { - [image drawInRect:rect]; +- (IBAction)click:(id)sender { + NSEvent *current_event = [NSApp currentEvent]; + MouseButton index = MouseButton::LEFT; + if (current_event) { + if (current_event.type == NSEventTypeLeftMouseDown) { + index = MouseButton::LEFT; + } else if (current_event.type == NSEventTypeRightMouseDown) { + index = MouseButton::RIGHT; + } else if (current_event.type == NSEventTypeOtherMouseDown) { + if ((int)[current_event buttonNumber] == 2) { + index = MouseButton::MIDDLE; + } else if ((int)[current_event buttonNumber] == 3) { + index = MouseButton::MB_XBUTTON1; + } else if ((int)[current_event buttonNumber] == 4) { + index = MouseButton::MB_XBUTTON2; + } + } } -} -- (void)processMouseEvent:(NSEvent *)event index:(MouseButton)index { DisplayServerMacOS *ds = (DisplayServerMacOS *)DisplayServer::get_singleton(); if (!ds) { return; @@ -71,31 +73,8 @@ } } -- (void)mouseDown:(NSEvent *)event { - [super mouseDown:event]; - if (([event modifierFlags] & NSEventModifierFlagControl)) { - [self processMouseEvent:event index:MouseButton::RIGHT]; - } else { - [self processMouseEvent:event index:MouseButton::LEFT]; - } -} - -- (void)rightMouseDown:(NSEvent *)event { - [super rightMouseDown:event]; - - [self processMouseEvent:event index:MouseButton::RIGHT]; -} - -- (void)otherMouseDown:(NSEvent *)event { - [super otherMouseDown:event]; - - if ((int)[event buttonNumber] == 2) { - [self processMouseEvent:event index:MouseButton::MIDDLE]; - } else if ((int)[event buttonNumber] == 3) { - [self processMouseEvent:event index:MouseButton::MB_XBUTTON1]; - } else if ((int)[event buttonNumber] == 4) { - [self processMouseEvent:event index:MouseButton::MB_XBUTTON2]; - } +- (void)setCallback:(const Callable &)callback { + cb = callback; } @end diff --git a/platform/macos/native_menu_macos.h b/platform/macos/native_menu_macos.h index c00a510fd53..894f6912b5b 100644 --- a/platform/macos/native_menu_macos.h +++ b/platform/macos/native_menu_macos.h @@ -85,6 +85,8 @@ public: virtual bool has_menu(const RID &p_rid) const override; virtual void free_menu(const RID &p_rid) override; + NSMenu *get_native_menu_handle(const RID &p_rid); + virtual Size2 get_size(const RID &p_rid) const override; virtual void popup(const RID &p_rid, const Vector2i &p_position) override; diff --git a/platform/macos/native_menu_macos.mm b/platform/macos/native_menu_macos.mm index 250b64dc046..27ad5209c49 100644 --- a/platform/macos/native_menu_macos.mm +++ b/platform/macos/native_menu_macos.mm @@ -243,6 +243,13 @@ void NativeMenuMacOS::free_menu(const RID &p_rid) { } } +NSMenu *NativeMenuMacOS::get_native_menu_handle(const RID &p_rid) { + MenuData *md = menus.get_or_null(p_rid); + ERR_FAIL_NULL_V(md, nullptr); + + return md->menu; +} + Size2 NativeMenuMacOS::get_size(const RID &p_rid) const { const MenuData *md = menus.get_or_null(p_rid); ERR_FAIL_NULL_V(md, Size2()); diff --git a/platform/windows/display_server_windows.cpp b/platform/windows/display_server_windows.cpp index 074d40bf4bd..cde7992b29b 100644 --- a/platform/windows/display_server_windows.cpp +++ b/platform/windows/display_server_windows.cpp @@ -3152,14 +3152,12 @@ void DisplayServerWindows::set_icon(const Ref &p_icon) { } } -DisplayServer::IndicatorID DisplayServerWindows::create_status_indicator(const Ref &p_icon, const String &p_tooltip, const Callable &p_callback) { +DisplayServer::IndicatorID DisplayServerWindows::create_status_indicator(const Ref &p_icon, const String &p_tooltip, const Callable &p_callback) { HICON hicon = nullptr; if (p_icon.is_valid() && p_icon->get_width() > 0 && p_icon->get_height() > 0) { - Ref img = p_icon; - if (img != icon) { - img = img->duplicate(); - img->convert(Image::FORMAT_RGBA8); - } + Ref img = p_icon->get_image(); + img = img->duplicate(); + img->convert(Image::FORMAT_RGBA8); int w = img->get_width(); int h = img->get_height(); @@ -3222,16 +3220,14 @@ DisplayServer::IndicatorID DisplayServerWindows::create_status_indicator(const R return iid; } -void DisplayServerWindows::status_indicator_set_icon(IndicatorID p_id, const Ref &p_icon) { +void DisplayServerWindows::status_indicator_set_icon(IndicatorID p_id, const Ref &p_icon) { ERR_FAIL_COND(!indicators.has(p_id)); HICON hicon = nullptr; if (p_icon.is_valid() && p_icon->get_width() > 0 && p_icon->get_height() > 0) { - Ref img = p_icon; - if (img != icon) { - img = img->duplicate(); - img->convert(Image::FORMAT_RGBA8); - } + Ref img = p_icon->get_image(); + img = img->duplicate(); + img->convert(Image::FORMAT_RGBA8); int w = img->get_width(); int h = img->get_height(); @@ -3298,6 +3294,12 @@ void DisplayServerWindows::status_indicator_set_tooltip(IndicatorID p_id, const Shell_NotifyIconW(NIM_MODIFY, &ndat); } +void DisplayServerWindows::status_indicator_set_menu(IndicatorID p_id, const RID &p_menu_rid) { + ERR_FAIL_COND(!indicators.has(p_id)); + + indicators[p_id].menu_rid = p_menu_rid; +} + void DisplayServerWindows::status_indicator_set_callback(IndicatorID p_id, const Callable &p_callback) { ERR_FAIL_COND(!indicators.has(p_id)); @@ -3850,7 +3852,19 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA mb = MouseButton::MB_XBUTTON1; } if (indicators.has(iid)) { - if (indicators[iid].callback.is_valid()) { + if (lParam == WM_RBUTTONDOWN && indicators[iid].menu_rid.is_valid() && native_menu->has_menu(indicators[iid].menu_rid)) { + NOTIFYICONIDENTIFIER nid; + ZeroMemory(&nid, sizeof(NOTIFYICONIDENTIFIER)); + nid.cbSize = sizeof(NOTIFYICONIDENTIFIER); + nid.hWnd = windows[MAIN_WINDOW_ID].hWnd; + nid.uID = iid; + nid.guidItem = GUID_NULL; + + RECT rect; + if (Shell_NotifyIconGetRect(&nid, &rect) == S_OK) { + native_menu->popup(indicators[iid].menu_rid, Vector2i((rect.left + rect.right) / 2, (rect.top + rect.bottom) / 2)); + } + } else if (indicators[iid].callback.is_valid()) { Variant v_button = mb; Variant v_pos = mouse_get_position(); Variant *v_args[2] = { &v_button, &v_pos }; diff --git a/platform/windows/display_server_windows.h b/platform/windows/display_server_windows.h index 1191f229687..1b2a9a20905 100644 --- a/platform/windows/display_server_windows.h +++ b/platform/windows/display_server_windows.h @@ -465,6 +465,7 @@ class DisplayServerWindows : public DisplayServer { WNDPROC user_proc = nullptr; struct IndicatorData { + RID menu_rid; Callable callback; }; @@ -686,9 +687,10 @@ public: virtual void set_native_icon(const String &p_filename) override; virtual void set_icon(const Ref &p_icon) override; - virtual IndicatorID create_status_indicator(const Ref &p_icon, const String &p_tooltip, const Callable &p_callback) override; - virtual void status_indicator_set_icon(IndicatorID p_id, const Ref &p_icon) override; + virtual IndicatorID create_status_indicator(const Ref &p_icon, const String &p_tooltip, const Callable &p_callback) override; + virtual void status_indicator_set_icon(IndicatorID p_id, const Ref &p_icon) override; virtual void status_indicator_set_tooltip(IndicatorID p_id, const String &p_tooltip) override; + virtual void status_indicator_set_menu(IndicatorID p_id, const RID &p_rid) override; virtual void status_indicator_set_callback(IndicatorID p_id, const Callable &p_callback) override; virtual void delete_status_indicator(IndicatorID p_id) override; diff --git a/scene/main/status_indicator.cpp b/scene/main/status_indicator.cpp index ae58bc0b183..cc367da175a 100644 --- a/scene/main/status_indicator.cpp +++ b/scene/main/status_indicator.cpp @@ -30,6 +30,8 @@ #include "status_indicator.h" +#include "scene/gui/popup_menu.h" + void StatusIndicator::_notification(int p_what) { ERR_MAIN_THREAD_GUARD; #ifdef TOOLS_ENABLED @@ -43,12 +45,22 @@ void StatusIndicator::_notification(int p_what) { if (DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_STATUS_INDICATOR)) { if (visible && iid == DisplayServer::INVALID_INDICATOR_ID) { iid = DisplayServer::get_singleton()->create_status_indicator(icon, tooltip, callable_mp(this, &StatusIndicator::_callback)); + PopupMenu *pm = Object::cast_to(get_node_or_null(menu)); + if (pm) { + RID menu_rid = pm->bind_global_menu(); + DisplayServer::get_singleton()->status_indicator_set_menu(iid, menu_rid); + } } } } break; case NOTIFICATION_EXIT_TREE: { if (DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_STATUS_INDICATOR)) { if (iid != DisplayServer::INVALID_INDICATOR_ID) { + PopupMenu *pm = Object::cast_to(get_node_or_null(menu)); + if (pm) { + pm->unbind_global_menu(); + DisplayServer::get_singleton()->status_indicator_set_menu(iid, RID()); + } DisplayServer::get_singleton()->delete_status_indicator(iid); iid = DisplayServer::INVALID_INDICATOR_ID; } @@ -66,11 +78,14 @@ void StatusIndicator::_bind_methods() { ClassDB::bind_method(D_METHOD("get_icon"), &StatusIndicator::get_icon); ClassDB::bind_method(D_METHOD("set_visible", "visible"), &StatusIndicator::set_visible); ClassDB::bind_method(D_METHOD("is_visible"), &StatusIndicator::is_visible); + ClassDB::bind_method(D_METHOD("set_menu", "menu"), &StatusIndicator::set_menu); + ClassDB::bind_method(D_METHOD("get_menu"), &StatusIndicator::get_menu); ADD_SIGNAL(MethodInfo("pressed", PropertyInfo(Variant::INT, "mouse_button"), PropertyInfo(Variant::VECTOR2I, "position"))); ADD_PROPERTY(PropertyInfo(Variant::STRING, "tooltip", PROPERTY_HINT_MULTILINE_TEXT), "set_tooltip", "get_tooltip"); - ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "icon", PROPERTY_HINT_RESOURCE_TYPE, "Image"), "set_icon", "get_icon"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "icon", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_icon", "get_icon"); + ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "menu", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "PopupMenu"), "set_menu", "get_menu"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "visible"), "set_visible", "is_visible"); } @@ -78,7 +93,7 @@ void StatusIndicator::_callback(MouseButton p_index, const Point2i &p_pos) { emit_signal(SNAME("pressed"), p_index, p_pos); } -void StatusIndicator::set_icon(const Ref &p_icon) { +void StatusIndicator::set_icon(const Ref &p_icon) { ERR_MAIN_THREAD_GUARD; icon = p_icon; if (iid != DisplayServer::INVALID_INDICATOR_ID) { @@ -86,7 +101,7 @@ void StatusIndicator::set_icon(const Ref &p_icon) { } } -Ref StatusIndicator::get_icon() const { +Ref StatusIndicator::get_icon() const { return icon; } @@ -102,6 +117,30 @@ String StatusIndicator::get_tooltip() const { return tooltip; } +void StatusIndicator::set_menu(const NodePath &p_menu) { + PopupMenu *pm = Object::cast_to(get_node_or_null(menu)); + if (pm) { + pm->unbind_global_menu(); + if (iid != DisplayServer::INVALID_INDICATOR_ID) { + DisplayServer::get_singleton()->status_indicator_set_menu(iid, RID()); + } + } + + menu = p_menu; + + pm = Object::cast_to(get_node_or_null(menu)); + if (pm) { + if (iid != DisplayServer::INVALID_INDICATOR_ID) { + RID menu_rid = pm->bind_global_menu(); + DisplayServer::get_singleton()->status_indicator_set_menu(iid, menu_rid); + } + } +} + +NodePath StatusIndicator::get_menu() const { + return menu; +} + void StatusIndicator::set_visible(bool p_visible) { ERR_MAIN_THREAD_GUARD; if (visible == p_visible) { @@ -122,8 +161,18 @@ void StatusIndicator::set_visible(bool p_visible) { if (DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_STATUS_INDICATOR)) { if (visible && iid == DisplayServer::INVALID_INDICATOR_ID) { iid = DisplayServer::get_singleton()->create_status_indicator(icon, tooltip, callable_mp(this, &StatusIndicator::_callback)); + PopupMenu *pm = Object::cast_to(get_node_or_null(menu)); + if (pm) { + RID menu_rid = pm->bind_global_menu(); + DisplayServer::get_singleton()->status_indicator_set_menu(iid, menu_rid); + } } if (!visible && iid != DisplayServer::INVALID_INDICATOR_ID) { + PopupMenu *pm = Object::cast_to(get_node_or_null(menu)); + if (pm) { + pm->unbind_global_menu(); + DisplayServer::get_singleton()->status_indicator_set_menu(iid, RID()); + } DisplayServer::get_singleton()->delete_status_indicator(iid); iid = DisplayServer::INVALID_INDICATOR_ID; } diff --git a/scene/main/status_indicator.h b/scene/main/status_indicator.h index aa3aa68d782..cc137391a91 100644 --- a/scene/main/status_indicator.h +++ b/scene/main/status_indicator.h @@ -37,10 +37,11 @@ class StatusIndicator : public Node { GDCLASS(StatusIndicator, Node); - Ref icon; + Ref icon; String tooltip; bool visible = true; DisplayServer::IndicatorID iid = DisplayServer::INVALID_INDICATOR_ID; + NodePath menu; protected: void _notification(int p_what); @@ -49,12 +50,15 @@ protected: void _callback(MouseButton p_index, const Point2i &p_pos); public: - void set_icon(const Ref &p_icon); - Ref get_icon() const; + void set_icon(const Ref &p_icon); + Ref get_icon() const; void set_tooltip(const String &p_tooltip); String get_tooltip() const; + void set_menu(const NodePath &p_menu); + NodePath get_menu() const; + void set_visible(bool p_visible); bool is_visible() const; }; diff --git a/servers/display_server.cpp b/servers/display_server.cpp index 72228c25f26..1de8104f733 100644 --- a/servers/display_server.cpp +++ b/servers/display_server.cpp @@ -713,12 +713,12 @@ void DisplayServer::set_icon(const Ref &p_icon) { WARN_PRINT("Icon not supported by this display server."); } -DisplayServer::IndicatorID DisplayServer::create_status_indicator(const Ref &p_icon, const String &p_tooltip, const Callable &p_callback) { +DisplayServer::IndicatorID DisplayServer::create_status_indicator(const Ref &p_icon, const String &p_tooltip, const Callable &p_callback) { WARN_PRINT("Status indicator not supported by this display server."); return INVALID_INDICATOR_ID; } -void DisplayServer::status_indicator_set_icon(IndicatorID p_id, const Ref &p_icon) { +void DisplayServer::status_indicator_set_icon(IndicatorID p_id, const Ref &p_icon) { WARN_PRINT("Status indicator not supported by this display server."); } @@ -726,6 +726,10 @@ void DisplayServer::status_indicator_set_tooltip(IndicatorID p_id, const String WARN_PRINT("Status indicator not supported by this display server."); } +void DisplayServer::status_indicator_set_menu(IndicatorID p_id, const RID &p_menu_rid) { + WARN_PRINT("Status indicator not supported by this display server."); +} + void DisplayServer::status_indicator_set_callback(IndicatorID p_id, const Callable &p_callback) { WARN_PRINT("Status indicator not supported by this display server."); } @@ -981,6 +985,7 @@ void DisplayServer::_bind_methods() { ClassDB::bind_method(D_METHOD("create_status_indicator", "icon", "tooltip", "callback"), &DisplayServer::create_status_indicator); ClassDB::bind_method(D_METHOD("status_indicator_set_icon", "id", "icon"), &DisplayServer::status_indicator_set_icon); ClassDB::bind_method(D_METHOD("status_indicator_set_tooltip", "id", "tooltip"), &DisplayServer::status_indicator_set_tooltip); + ClassDB::bind_method(D_METHOD("status_indicator_set_menu", "id", "menu_rid"), &DisplayServer::status_indicator_set_menu); ClassDB::bind_method(D_METHOD("status_indicator_set_callback", "id", "callback"), &DisplayServer::status_indicator_set_callback); ClassDB::bind_method(D_METHOD("delete_status_indicator", "id"), &DisplayServer::delete_status_indicator); diff --git a/servers/display_server.h b/servers/display_server.h index 85b791ca690..2f856171142 100644 --- a/servers/display_server.h +++ b/servers/display_server.h @@ -563,9 +563,10 @@ public: virtual void set_native_icon(const String &p_filename); virtual void set_icon(const Ref &p_icon); - virtual IndicatorID create_status_indicator(const Ref &p_icon, const String &p_tooltip, const Callable &p_callback); - virtual void status_indicator_set_icon(IndicatorID p_id, const Ref &p_icon); + virtual IndicatorID create_status_indicator(const Ref &p_icon, const String &p_tooltip, const Callable &p_callback); + virtual void status_indicator_set_icon(IndicatorID p_id, const Ref &p_icon); virtual void status_indicator_set_tooltip(IndicatorID p_id, const String &p_tooltip); + virtual void status_indicator_set_menu(IndicatorID p_id, const RID &p_menu_rid); virtual void status_indicator_set_callback(IndicatorID p_id, const Callable &p_callback); virtual void delete_status_indicator(IndicatorID p_id);