From 84650f20181ad73f52f7d8faaa251656b1c54870 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pa=CC=84vels=20Nadtoc=CC=8Cajevs?= <7645683+bruvzg@users.noreply.github.com> Date: Sun, 17 Nov 2024 22:40:39 +0200 Subject: [PATCH] Implement `DisplayServer.beep`. --- doc/classes/DisplayServer.xml | 7 +++ platform/linuxbsd/wayland/SCsub | 11 ++++ .../wayland/display_server_wayland.cpp | 4 ++ .../linuxbsd/wayland/display_server_wayland.h | 2 + platform/linuxbsd/wayland/wayland_thread.cpp | 27 +++++++++ platform/linuxbsd/wayland/wayland_thread.h | 6 ++ platform/linuxbsd/x11/display_server_x11.cpp | 4 ++ platform/linuxbsd/x11/display_server_x11.h | 2 + platform/macos/display_server_macos.h | 2 + platform/macos/display_server_macos.mm | 4 ++ platform/windows/display_server_windows.cpp | 4 ++ platform/windows/display_server_windows.h | 2 + servers/display_server.cpp | 5 ++ servers/display_server.h | 2 + thirdparty/README.md | 1 + .../staging/xdg-system-bell/README | 5 ++ .../xdg-system-bell/xdg-system-bell-v1.xml | 58 +++++++++++++++++++ 17 files changed, 146 insertions(+) create mode 100644 thirdparty/wayland-protocols/staging/xdg-system-bell/README create mode 100644 thirdparty/wayland-protocols/staging/xdg-system-bell/xdg-system-bell-v1.xml diff --git a/doc/classes/DisplayServer.xml b/doc/classes/DisplayServer.xml index a997eef0db..fea38aad55 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 1a8e243728..f3a554a58d 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 fe359532bb..e321e4d4b9 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 e611533664..d6f51b4a7e 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 d8d58ba54b..f1aac4f069 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 819a1205d6..c07694b52a 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 a9c94bd823..90bd3d57d4 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 0cbfbe51ef..31e4d548b9 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 5e2e1b8162..1cb4abc205 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 4b873e02b4..476e508a55 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 bd629ea400..8e2d47709f 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 d0e0533a3e..c6b8693a9d 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 0fcbfb02cf..ff9a07f397 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 954093c5cb..805d2374ab 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 79d7e5b7b6..1e11c6c972 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 0000000000..a9276e16b3 --- /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 0000000000..f00508de85 --- /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. + + + + +