From 78baaca4a336be42ff972c1869caf1e278c8ca75 Mon Sep 17 00:00:00 2001 From: ardocrat Date: Thu, 29 May 2025 15:37:00 +0300 Subject: [PATCH] fix: keyboard modal focus --- src/gui/views/input/edit.rs | 2 +- src/gui/views/input/keyboard.rs | 6 +++++- src/gui/views/modal.rs | 26 ++++++++++++++++++-------- 3 files changed, 24 insertions(+), 10 deletions(-) diff --git a/src/gui/views/input/edit.rs b/src/gui/views/input/edit.rs index c95a8ecf..39a3c446 100644 --- a/src/gui/views/input/edit.rs +++ b/src/gui/views/input/edit.rs @@ -125,7 +125,7 @@ impl TextEdit { let mut edit_rect = ui.available_rect_before_wrap(); edit_rect.set_height(Self::TEXT_EDIT_HEIGHT); - // Setup focused input value. + // Setup focused input value to avoid dismiss when click on keyboard. let focused_input_id = egui::Id::new("focused_input_id"); let focused = ui.data(|data| { data.get_temp(focused_input_id) diff --git a/src/gui/views/input/keyboard.rs b/src/gui/views/input/keyboard.rs index 735abf60..fc5e9aa6 100644 --- a/src/gui/views/input/keyboard.rs +++ b/src/gui/views/input/keyboard.rs @@ -12,6 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +use std::string::ToString; use egui::{Align, Align2, Button, Color32, CursorIcon, Layout, Margin, Rect, Response, RichText, Sense, Shadow, Vec2, Widget}; use lazy_static::lazy_static; use parking_lot::RwLock; @@ -50,10 +51,13 @@ impl KeyboardContent { /// Maximum numbers layout width. const MAX_WIDTH_NUMBERS: f32 = 400.0; + /// Keyboard window id. + pub const WINDOW_ID: &'static str = "soft_keyboard_window"; + /// Draw keyboard content as separate [`Window`]. pub fn window_ui(&mut self, numeric: bool, ctx: &egui::Context) { let width = ctx.screen_rect().width(); - let layer_id = egui::Window::new("soft_keyboard") + let layer_id = egui::Window::new(Self::WINDOW_ID) .title_bar(false) .resizable(false) .collapsible(false) diff --git a/src/gui/views/modal.rs b/src/gui/views/modal.rs index 2d36a10c..7fd38494 100755 --- a/src/gui/views/modal.rs +++ b/src/gui/views/modal.rs @@ -14,14 +14,14 @@ use egui::epaint::{RectShape, Shadow}; use egui::os::OperatingSystem; -use egui::{Align2, CornerRadius, RichText, Stroke, StrokeKind, UiBuilder, Vec2}; +use egui::{Align2, CornerRadius, Order, RichText, Stroke, StrokeKind, UiBuilder, Vec2}; use lazy_static::lazy_static; use parking_lot::RwLock; use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::Arc; use crate::gui::views::types::{ModalPosition, ModalState}; -use crate::gui::views::{Content, View}; +use crate::gui::views::{Content, KeyboardContent, View}; use crate::gui::Colors; lazy_static! { @@ -109,6 +109,7 @@ impl Modal { /// Set [`Modal`] instance into state to show at ui. pub fn show(self) { let mut w_nav = MODAL_STATE.write(); + self.first_draw.store(true, Ordering::Relaxed); w_nav.modal = Some(self); } @@ -225,7 +226,7 @@ impl Modal { // Show main content window at given position. let (content_align, content_offset) = self.modal_position(); - let layer_id = egui::Window::new("modal_window") + let res = egui::Window::new("modal_window") .title_bar(false) .resizable(false) .collapsible(false) @@ -247,13 +248,22 @@ impl Modal { title_ui(title, ui); } self.content_ui(ui, add_content); - }).unwrap().response.layer_id; - + + }).unwrap().response; + + // Show modal or keyboard window above others. + ctx.move_to_top(res.layer_id); + let keyboard_showing = if let Some(l) = ctx.top_layer_id() { + l.id == egui::Id::new(KeyboardContent::WINDOW_ID) + } else { + false + }; + if keyboard_showing { + ctx.move_to_top(egui::LayerId::new(Order::Middle, egui::Id::new(KeyboardContent::WINDOW_ID))) + } + // Setup first draw flag. if Self::first_draw() { - // Always show main content window above background window. - ctx.move_to_top(layer_id); - let r_state = MODAL_STATE.read(); let modal = r_state.modal.as_ref().unwrap(); modal.first_draw.store(false, Ordering::Relaxed);