diff --git a/doc/classes/DisplayServer.xml b/doc/classes/DisplayServer.xml index a997eef0dbe..fea38aad55c 100644 --- a/doc/classes/DisplayServer.xml +++ b/doc/classes/DisplayServer.xml @@ -10,6 +10,13 @@ + + + + Plays the beep sound from the operative system, if possible. Because it comes from the OS, the beep sound will be audible even if the application is muted. It may also be disabled for the entire OS by the user. + [b]Note:[/b] This method is implemented on macOS, Linux (X11/Wayland), and Windows. + + diff --git a/platform/linuxbsd/wayland/SCsub b/platform/linuxbsd/wayland/SCsub index 1a8e243728b..f3a554a58db 100644 --- a/platform/linuxbsd/wayland/SCsub +++ b/platform/linuxbsd/wayland/SCsub @@ -172,11 +172,22 @@ env.WAYLAND_API_CODE( source="#thirdparty/wayland-protocols/unstable/xdg-foreign/xdg-foreign-unstable-v1.xml", ) +env.WAYLAND_API_HEADER( + target="protocol/xdg_system_bell.gen.h", + source="#thirdparty/wayland-protocols/staging/xdg-system-bell/xdg-system-bell-v1.xml", +) + +env.WAYLAND_API_CODE( + target="protocol/xdg_system_bell.gen.c", + source="#thirdparty/wayland-protocols/staging/xdg-system-bell/xdg-system-bell-v1.xml", +) + source_files = [ "protocol/wayland.gen.c", "protocol/viewporter.gen.c", "protocol/fractional_scale.gen.c", "protocol/xdg_shell.gen.c", + "protocol/xdg_system_bell.gen.c", "protocol/xdg_foreign.gen.c", "protocol/xdg_decoration.gen.c", "protocol/xdg_activation.gen.c", diff --git a/platform/linuxbsd/wayland/display_server_wayland.cpp b/platform/linuxbsd/wayland/display_server_wayland.cpp index fe359532bb0..e321e4d4b94 100644 --- a/platform/linuxbsd/wayland/display_server_wayland.cpp +++ b/platform/linuxbsd/wayland/display_server_wayland.cpp @@ -319,6 +319,10 @@ Error DisplayServerWayland::file_dialog_with_options_show(const String &p_title, #endif +void DisplayServerWayland::beep() const { + wayland_thread.beep(); +} + void DisplayServerWayland::mouse_set_mode(MouseMode p_mode) { if (p_mode == mouse_mode) { return; diff --git a/platform/linuxbsd/wayland/display_server_wayland.h b/platform/linuxbsd/wayland/display_server_wayland.h index e6115336642..d6f51b4a7e9 100644 --- a/platform/linuxbsd/wayland/display_server_wayland.h +++ b/platform/linuxbsd/wayland/display_server_wayland.h @@ -181,6 +181,8 @@ public: virtual Error file_dialog_with_options_show(const String &p_title, const String &p_current_directory, const String &p_root, const String &p_filename, bool p_show_hidden, FileDialogMode p_mode, const Vector &p_filters, const TypedArray &p_options, const Callable &p_callback) override; #endif + virtual void beep() const override; + virtual void mouse_set_mode(MouseMode p_mode) override; virtual MouseMode mouse_get_mode() const override; diff --git a/platform/linuxbsd/wayland/wayland_thread.cpp b/platform/linuxbsd/wayland/wayland_thread.cpp index d8d58ba54b9..f1aac4f0696 100644 --- a/platform/linuxbsd/wayland/wayland_thread.cpp +++ b/platform/linuxbsd/wayland/wayland_thread.cpp @@ -497,6 +497,12 @@ void WaylandThread::_wl_registry_on_global(void *data, struct wl_registry *wl_re return; } + if (strcmp(interface, xdg_system_bell_v1_interface.name) == 0) { + registry->xdg_system_bell = (struct xdg_system_bell_v1 *)wl_registry_bind(wl_registry, name, &xdg_system_bell_v1_interface, 1); + registry->xdg_system_bell_name = name; + return; + } + if (strcmp(interface, xdg_activation_v1_interface.name) == 0) { registry->xdg_activation = (struct xdg_activation_v1 *)wl_registry_bind(wl_registry, name, &xdg_activation_v1_interface, 1); registry->xdg_activation_name = name; @@ -692,6 +698,17 @@ void WaylandThread::_wl_registry_on_global_remove(void *data, struct wl_registry return; } + if (name == registry->xdg_system_bell_name) { + if (registry->xdg_system_bell) { + xdg_system_bell_v1_destroy(registry->xdg_system_bell); + registry->xdg_system_bell = nullptr; + } + + registry->xdg_system_bell_name = 0; + + return; + } + if (name == registry->xdg_activation_name) { if (registry->xdg_activation) { xdg_activation_v1_destroy(registry->xdg_activation); @@ -3282,6 +3299,12 @@ struct wl_surface *WaylandThread::window_get_wl_surface(DisplayServer::WindowID return ws.wl_surface; } +void WaylandThread::beep() const { + if (registry.xdg_system_bell) { + xdg_system_bell_v1_ring(registry.xdg_system_bell, nullptr); + } +} + void WaylandThread::window_set_max_size(DisplayServer::WindowID p_window_id, const Size2i &p_size) { // TODO: Use window IDs for multiwindow support. WindowState &ws = main_window; @@ -4364,6 +4387,10 @@ void WaylandThread::destroy() { xdg_activation_v1_destroy(registry.xdg_activation); } + if (registry.xdg_system_bell) { + xdg_system_bell_v1_destroy(registry.xdg_system_bell); + } + if (registry.xdg_decoration_manager) { zxdg_decoration_manager_v1_destroy(registry.xdg_decoration_manager); } diff --git a/platform/linuxbsd/wayland/wayland_thread.h b/platform/linuxbsd/wayland/wayland_thread.h index 819a1205d68..c07694b52ae 100644 --- a/platform/linuxbsd/wayland/wayland_thread.h +++ b/platform/linuxbsd/wayland/wayland_thread.h @@ -69,6 +69,7 @@ #include "wayland/protocol/xdg_decoration.gen.h" #include "wayland/protocol/xdg_foreign.gen.h" #include "wayland/protocol/xdg_shell.gen.h" +#include "wayland/protocol/xdg_system_bell.gen.h" #ifdef LIBDECOR_ENABLED #ifdef SOWRAP_ENABLED @@ -162,6 +163,9 @@ public: struct zxdg_decoration_manager_v1 *xdg_decoration_manager = nullptr; uint32_t xdg_decoration_manager_name = 0; + struct xdg_system_bell_v1 *xdg_system_bell = nullptr; + uint32_t xdg_system_bell_name = 0; + struct xdg_activation_v1 *xdg_activation = nullptr; uint32_t xdg_activation_name = 0; @@ -926,6 +930,8 @@ public: bool has_message(); Ref pop_message(); + void beep() const; + void window_create(DisplayServer::WindowID p_window_id, int p_width, int p_height); struct wl_surface *window_get_wl_surface(DisplayServer::WindowID p_window_id) const; diff --git a/platform/linuxbsd/x11/display_server_x11.cpp b/platform/linuxbsd/x11/display_server_x11.cpp index a9c94bd8238..90bd3d57d4b 100644 --- a/platform/linuxbsd/x11/display_server_x11.cpp +++ b/platform/linuxbsd/x11/display_server_x11.cpp @@ -400,6 +400,10 @@ Error DisplayServerX11::file_dialog_with_options_show(const String &p_title, con #endif +void DisplayServerX11::beep() const { + XBell(x11_display, 0); +} + void DisplayServerX11::mouse_set_mode(MouseMode p_mode) { _THREAD_SAFE_METHOD_ diff --git a/platform/linuxbsd/x11/display_server_x11.h b/platform/linuxbsd/x11/display_server_x11.h index 0cbfbe51ef1..31e4d548b9a 100644 --- a/platform/linuxbsd/x11/display_server_x11.h +++ b/platform/linuxbsd/x11/display_server_x11.h @@ -406,6 +406,8 @@ public: virtual Error file_dialog_with_options_show(const String &p_title, const String &p_current_directory, const String &p_root, const String &p_filename, bool p_show_hidden, FileDialogMode p_mode, const Vector &p_filters, const TypedArray &p_options, const Callable &p_callback) override; #endif + virtual void beep() const override; + virtual void mouse_set_mode(MouseMode p_mode) override; virtual MouseMode mouse_get_mode() const override; diff --git a/platform/macos/display_server_macos.h b/platform/macos/display_server_macos.h index 5e2e1b81622..1cb4abc2052 100644 --- a/platform/macos/display_server_macos.h +++ b/platform/macos/display_server_macos.h @@ -298,6 +298,8 @@ public: virtual Error file_dialog_show(const String &p_title, const String &p_current_directory, const String &p_filename, bool p_show_hidden, FileDialogMode p_mode, const Vector &p_filters, const Callable &p_callback) override; virtual Error file_dialog_with_options_show(const String &p_title, const String &p_current_directory, const String &p_root, const String &p_filename, bool p_show_hidden, FileDialogMode p_mode, const Vector &p_filters, const TypedArray &p_options, const Callable &p_callback) override; + virtual void beep() const override; + virtual void mouse_set_mode(MouseMode p_mode) override; virtual MouseMode mouse_get_mode() const override; diff --git a/platform/macos/display_server_macos.mm b/platform/macos/display_server_macos.mm index 4b873e02b4e..476e508a554 100644 --- a/platform/macos/display_server_macos.mm +++ b/platform/macos/display_server_macos.mm @@ -1200,6 +1200,10 @@ Error DisplayServerMacOS::_file_dialog_with_options_show(const String &p_title, return OK; } +void DisplayServerMacOS::beep() const { + NSBeep(); +} + Error DisplayServerMacOS::dialog_input_text(String p_title, String p_description, String p_partial, const Callable &p_callback) { _THREAD_SAFE_METHOD_ diff --git a/platform/windows/display_server_windows.cpp b/platform/windows/display_server_windows.cpp index bd629ea4009..8e2d47709f9 100644 --- a/platform/windows/display_server_windows.cpp +++ b/platform/windows/display_server_windows.cpp @@ -786,6 +786,10 @@ void DisplayServerWindows::process_file_dialog_callbacks() { } } +void DisplayServerWindows::beep() const { + MessageBeep(MB_OK); +} + void DisplayServerWindows::mouse_set_mode(MouseMode p_mode) { _THREAD_SAFE_METHOD_ diff --git a/platform/windows/display_server_windows.h b/platform/windows/display_server_windows.h index d0e0533a3e3..c6b8693a9d5 100644 --- a/platform/windows/display_server_windows.h +++ b/platform/windows/display_server_windows.h @@ -689,6 +689,8 @@ public: virtual Error file_dialog_show(const String &p_title, const String &p_current_directory, const String &p_filename, bool p_show_hidden, FileDialogMode p_mode, const Vector &p_filters, const Callable &p_callback) override; virtual Error file_dialog_with_options_show(const String &p_title, const String &p_current_directory, const String &p_root, const String &p_filename, bool p_show_hidden, FileDialogMode p_mode, const Vector &p_filters, const TypedArray &p_options, const Callable &p_callback) override; + virtual void beep() const override; + virtual void mouse_set_mode(MouseMode p_mode) override; virtual MouseMode mouse_get_mode() const override; diff --git a/servers/display_server.cpp b/servers/display_server.cpp index 0fcbfb02cf5..ff9a07f3970 100644 --- a/servers/display_server.cpp +++ b/servers/display_server.cpp @@ -677,6 +677,9 @@ Error DisplayServer::file_dialog_with_options_show(const String &p_title, const return ERR_UNAVAILABLE; } +void DisplayServer::beep() const { +} + int DisplayServer::keyboard_get_layout_count() const { return 0; } @@ -998,6 +1001,8 @@ void DisplayServer::_bind_methods() { ClassDB::bind_method(D_METHOD("file_dialog_show", "title", "current_directory", "filename", "show_hidden", "mode", "filters", "callback"), &DisplayServer::file_dialog_show); ClassDB::bind_method(D_METHOD("file_dialog_with_options_show", "title", "current_directory", "root", "filename", "show_hidden", "mode", "filters", "options", "callback"), &DisplayServer::file_dialog_with_options_show); + ClassDB::bind_method(D_METHOD("beep"), &DisplayServer::beep); + ClassDB::bind_method(D_METHOD("keyboard_get_layout_count"), &DisplayServer::keyboard_get_layout_count); ClassDB::bind_method(D_METHOD("keyboard_get_current_layout"), &DisplayServer::keyboard_get_current_layout); ClassDB::bind_method(D_METHOD("keyboard_set_current_layout", "index"), &DisplayServer::keyboard_set_current_layout); diff --git a/servers/display_server.h b/servers/display_server.h index 954093c5cb7..805d2374ab0 100644 --- a/servers/display_server.h +++ b/servers/display_server.h @@ -560,6 +560,8 @@ public: virtual Error file_dialog_show(const String &p_title, const String &p_current_directory, const String &p_filename, bool p_show_hidden, FileDialogMode p_mode, const Vector &p_filters, const Callable &p_callback); virtual Error file_dialog_with_options_show(const String &p_title, const String &p_current_directory, const String &p_root, const String &p_filename, bool p_show_hidden, FileDialogMode p_mode, const Vector &p_filters, const TypedArray &p_options, const Callable &p_callback); + virtual void beep() const; + virtual int keyboard_get_layout_count() const; virtual int keyboard_get_current_layout() const; virtual void keyboard_set_current_layout(int p_index); diff --git a/thirdparty/README.md b/thirdparty/README.md index 79d7e5b7b6a..1e11c6c9725 100644 --- a/thirdparty/README.md +++ b/thirdparty/README.md @@ -1026,6 +1026,7 @@ Files extracted from upstream source: - `staging/fractional-scale/fractional-scale-v1.xml` - `staging/xdg-activation/README` - `staging/xdg-activation/xdg-activation-v1.xml` +- `staging/xdg-system-bell/xdg-system-bell-v1.xml` - `unstable/idle-inhibit/README` - `unstable/idle-inhibit/idle-inhibit-unstable-v1.xml` - `unstable/pointer-constraints/README` diff --git a/thirdparty/wayland-protocols/staging/xdg-system-bell/README b/thirdparty/wayland-protocols/staging/xdg-system-bell/README new file mode 100644 index 00000000000..a9276e16b36 --- /dev/null +++ b/thirdparty/wayland-protocols/staging/xdg-system-bell/README @@ -0,0 +1,5 @@ +system_bell protocol + +Maintainers: +Jonas Ådahl +Carlos Garnacho diff --git a/thirdparty/wayland-protocols/staging/xdg-system-bell/xdg-system-bell-v1.xml b/thirdparty/wayland-protocols/staging/xdg-system-bell/xdg-system-bell-v1.xml new file mode 100644 index 00000000000..f00508de850 --- /dev/null +++ b/thirdparty/wayland-protocols/staging/xdg-system-bell/xdg-system-bell-v1.xml @@ -0,0 +1,58 @@ + + + + Copyright © 2016, 2023 Red Hat + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice (including the next + paragraph) shall be included in all copies or substantial portions of the + Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. + + + + + This global interface enables clients to ring the system bell. + + Warning! The protocol described in this file is currently in the testing + phase. Backward compatible changes may be added together with the + corresponding interface version bump. Backward incompatible changes can + only be done by creating a new major version of the extension. + + + + + Notify that the object will no longer be used. + + + + + + This requests rings the system bell on behalf of a client. How ringing + the bell is implemented is up to the compositor. It may be an audible + sound, a visual feedback of some kind, or any other thing including + nothing. + + The passed surface should correspond to a toplevel like surface role, + or be null, meaning the client doesn't have a particular toplevel it + wants to associate the bell ringing with. See the xdg-shell protocol + extension for a toplevel like surface role. + + + + +