diff options
Diffstat (limited to 'platform/linuxbsd/wayland/display_server_wayland.cpp')
-rw-r--r-- | platform/linuxbsd/wayland/display_server_wayland.cpp | 85 |
1 files changed, 49 insertions, 36 deletions
diff --git a/platform/linuxbsd/wayland/display_server_wayland.cpp b/platform/linuxbsd/wayland/display_server_wayland.cpp index b8a10ea6b9..d552dd7b8a 100644 --- a/platform/linuxbsd/wayland/display_server_wayland.cpp +++ b/platform/linuxbsd/wayland/display_server_wayland.cpp @@ -193,18 +193,29 @@ void DisplayServerWayland::_show_window() { bool DisplayServerWayland::has_feature(Feature p_feature) const { switch (p_feature) { case FEATURE_MOUSE: + case FEATURE_MOUSE_WARP: case FEATURE_CLIPBOARD: case FEATURE_CURSOR_SHAPE: + case FEATURE_CUSTOM_CURSOR_SHAPE: case FEATURE_WINDOW_TRANSPARENCY: + case FEATURE_HIDPI: case FEATURE_SWAP_BUFFERS: case FEATURE_KEEP_SCREEN_ON: - case FEATURE_CLIPBOARD_PRIMARY: + case FEATURE_CLIPBOARD_PRIMARY: { + return true; + } break; + #ifdef DBUS_ENABLED - case FEATURE_NATIVE_DIALOG: + case FEATURE_NATIVE_DIALOG: { + return true; + } break; #endif - case FEATURE_HIDPI: { + +#ifdef SPEECHD_ENABLED + case FEATURE_TEXT_TO_SPEECH: { return true; } break; +#endif default: { return false; @@ -275,6 +286,10 @@ bool DisplayServerWayland::is_dark_mode() const { } } +void DisplayServerWayland::set_system_theme_change_callback(const Callable &p_callable) { + portal_desktop->set_system_theme_change_callback(p_callable); +} + Error DisplayServerWayland::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<String> &p_filters, const Callable &p_callback) { WindowID window_id = MAIN_WINDOW_ID; // TODO: Use window IDs for multiwindow support. @@ -863,11 +878,11 @@ bool DisplayServerWayland::window_is_focused(WindowID p_window_id) const { } bool DisplayServerWayland::window_can_draw(DisplayServer::WindowID p_window_id) const { - return frame; + return !suspended; } bool DisplayServerWayland::can_any_window_draw() const { - return frame; + return !suspended; } void DisplayServerWayland::window_set_ime_active(const bool p_active, DisplayServer::WindowID p_window_id) { @@ -986,36 +1001,9 @@ void DisplayServerWayland::cursor_set_custom_image(const Ref<Resource> &p_cursor wayland_thread.cursor_shape_clear_custom_image(p_shape); } - Ref<Texture2D> texture = p_cursor; - ERR_FAIL_COND(!texture.is_valid()); - Size2i texture_size; - - Ref<AtlasTexture> atlas_texture = texture; - - if (atlas_texture.is_valid()) { - texture_size.width = atlas_texture->get_region().size.x; - texture_size.height = atlas_texture->get_region().size.y; - } else { - texture_size.width = texture->get_width(); - texture_size.height = texture->get_height(); - } - - ERR_FAIL_COND(p_hotspot.x < 0 || p_hotspot.y < 0); - - // NOTE: The Wayland protocol says nothing about cursor size limits, yet if - // the texture is larger than 256x256 it won't show at least on sway. - ERR_FAIL_COND(texture_size.width > 256 || texture_size.height > 256); - ERR_FAIL_COND(p_hotspot.x > texture_size.width || p_hotspot.y > texture_size.height); - ERR_FAIL_COND(texture_size.height == 0 || texture_size.width == 0); - - Ref<Image> image = texture->get_image(); - ERR_FAIL_COND(!image.is_valid()); - - if (image->is_compressed()) { - image = image->duplicate(true); - Error err = image->decompress(); - ERR_FAIL_COND_MSG(err != OK, "Couldn't decompress VRAM-compressed custom mouse cursor image. Switch to a lossless compression mode in the Import dock."); - } + Rect2 atlas_rect; + Ref<Image> image = _get_cursor_image_from_resource(p_cursor, p_hotspot, atlas_rect); + ERR_FAIL_COND(image.is_null()); CustomCursor &cursor = custom_cursors[p_shape]; @@ -1139,7 +1127,32 @@ void DisplayServerWayland::process_events() { wayland_thread.keyboard_echo_keys(); - frame = wayland_thread.get_reset_frame(); + if (!suspended) { + if (emulate_vsync) { + // Due to various reasons, we manually handle display synchronization by + // waiting for a frame event (request to draw) or, if available, the actual + // window's suspend status. When a window is suspended, we can avoid drawing + // altogether, either because the compositor told us that we don't need to or + // because the pace of the frame events became unreliable. + bool frame = wayland_thread.wait_frame_suspend_ms(1000); + if (!frame) { + suspended = true; + } + } else { + if (wayland_thread.is_suspended()) { + suspended = true; + } + } + + if (suspended) { + DEBUG_LOG_WAYLAND("Window suspended."); + } + } else { + if (wayland_thread.get_reset_frame()) { + // At last, a sign of life! We're no longer suspended. + suspended = false; + } + } wayland_thread.mutex.unlock(); |