Skip to content

Commit 6f6f783

Browse files
committed
chore: ime bug in multi_window fixed
1 parent 350d78f commit 6f6f783

File tree

8 files changed

+63
-35
lines changed

8 files changed

+63
-35
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ window_clipboard = "0.4.1"
7878

7979
bitflags = "2.9.0"
8080
log = "0.4.22"
81+
enumflags2 = "0.7.11"
8182

8283
xkbcommon-dl = "0.4.2"
8384
smol_str = "0.2.2" #NOTE: follow iced

iced_layershell/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,3 +24,4 @@ layershellev.workspace = true
2424
window_clipboard.workspace = true
2525
log.workspace = true
2626
futures.workspace = true
27+
enumflags2.workspace = true

iced_layershell/src/actions.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1+
use crate::ime_preedit::ImeState;
12
use crate::reexport::{Anchor, Layer, WlRegion};
3+
use enumflags2::BitFlags;
24
use iced::window::Id as IcedId;
35
use iced_core::input_method;
46
use iced_core::mouse::Interaction;
@@ -18,7 +20,7 @@ pub(crate) enum LayerShellAction {
1820
RedrawWindow(LayerId), // maybe one day it is useful, but now useless
1921
NewMenu(IcedNewPopupSettings, iced_core::window::Id),
2022
Ime(input_method::InputMethod),
21-
ImeWithId(LayerId, input_method::InputMethod),
23+
ImeWithId(LayerId, input_method::InputMethod, BitFlags<ImeState>),
2224
}
2325

2426
#[derive(Debug, PartialEq, Eq, Clone, Copy)]

iced_layershell/src/ime_preedit.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ use iced_core::{
22
Color, Padding, Point, Rectangle, Size, Text, Vector, alignment, input_method, renderer, text,
33
};
44

5+
use enumflags2::bitflags;
6+
57
pub struct Preedit<Renderer>
68
where
79
Renderer: text::Renderer,
@@ -11,6 +13,14 @@ where
1113
spans: Vec<text::Span<'static, (), Renderer::Font>>,
1214
}
1315

16+
#[bitflags]
17+
#[derive(Debug, Clone, Copy)]
18+
#[repr(u64)]
19+
pub enum ImeState {
20+
ToBeAllowed = 1,
21+
ToBeUpdate = 2,
22+
}
23+
1424
impl<Renderer> Preedit<Renderer>
1525
where
1626
Renderer: text::Renderer,

iced_layershell/src/multi_window.rs

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -467,23 +467,30 @@ where
467467
}
468468
}
469469
}
470-
LayerShellAction::ImeWithId(id, ime) => match ime{
470+
LayerShellAction::ImeWithId(id, ime, ime_flags) => match ime{
471+
471472
iced_core::InputMethod::Disabled => {
472-
ev.set_ime_allowed(false);
473+
ev.set_ime_allowed_with_id(false, id);
473474
}
474475
iced_core::InputMethod::Enabled {
475476
position, purpose, ..
476477
} => {
477-
ev.set_ime_allowed(true);
478-
ev.set_ime_purpose(conversion::ime_purpose(purpose));
479-
ev.set_ime_cursor_area(
480-
layershellev::dpi::LogicalPosition::new(position.x, position.y),
481-
layershellev::dpi::LogicalSize {
482-
width: 10,
483-
height: 10,
484-
},
485-
id,
486-
);
478+
use crate::ime_preedit::ImeState;
479+
if ime_flags.contains(ImeState::ToBeAllowed) {
480+
ev.set_ime_allowed(true);
481+
}
482+
483+
if ime_flags.contains(ImeState::ToBeUpdate) {
484+
ev.set_ime_purpose(conversion::ime_purpose(purpose));
485+
ev.set_ime_cursor_area(
486+
layershellev::dpi::LogicalPosition::new(position.x, position.y),
487+
layershellev::dpi::LogicalSize {
488+
width: 10,
489+
height: 10,
490+
},
491+
id,
492+
);
493+
}
487494
}
488495
},
489496
LayerShellAction::NewMenu(menusettings, info) => 'out: {
@@ -693,11 +700,12 @@ async fn run_instance<A, E, C>(
693700
} = ui_state
694701
{
695702
events.push((Some(id), redraw_event.clone()));
703+
let need_update_ime = window.request_input_method(input_method.clone());
696704
custom_actions.push(LayerShellAction::ImeWithId(
697705
oid.expect("id should exist when refreshing"),
698-
input_method.clone(),
706+
input_method,
707+
need_update_ime,
699708
));
700-
window.request_input_method(input_method);
701709
}
702710

703711
window.draw_preedit();

iced_layershell/src/multi_window/window_manager.rs

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@ use std::{collections::BTreeMap, sync::Arc};
22

33
use super::state::State;
44
use crate::DefaultStyle;
5-
use crate::ime_preedit::Preedit;
5+
use crate::ime_preedit::{ImeState, Preedit};
66
use crate::multi_window::Application;
7+
use enumflags2::{BitFlag, BitFlags};
78
use iced_core::InputMethod;
89
use iced_core::input_method;
910
use iced_graphics::Compositor;
@@ -149,17 +150,25 @@ where
149150
C: Compositor<Renderer = A::Renderer>,
150151
A::Theme: DefaultStyle,
151152
{
152-
pub fn request_input_method(&mut self, input_method: InputMethod) {
153+
pub fn request_input_method(&mut self, input_method: InputMethod) -> BitFlags<ImeState> {
153154
match input_method {
154155
InputMethod::Disabled => {
155156
self.disable_ime();
157+
ImeState::empty()
156158
}
157159
InputMethod::Enabled {
158160
position,
159161
purpose,
160162
preedit,
161163
} => {
162-
self.enable_ime(position, purpose);
164+
let mut flags = ImeState::empty();
165+
if self.ime_state.is_none() {
166+
flags.insert(ImeState::ToBeAllowed);
167+
}
168+
if self.ime_state != Some((position, purpose)) {
169+
flags.insert(ImeState::ToBeUpdate);
170+
}
171+
self.update_ime(position, purpose);
163172

164173
if let Some(preedit) = preedit {
165174
if preedit.content.is_empty() {
@@ -179,6 +188,8 @@ where
179188
} else {
180189
self.preedit = None;
181190
}
191+
192+
flags
182193
}
183194
}
184195
}
@@ -196,7 +207,7 @@ where
196207
}
197208
}
198209

199-
fn enable_ime(&mut self, position: iced_core::Point, purpose: input_method::Purpose) {
210+
fn update_ime(&mut self, position: iced_core::Point, purpose: input_method::Purpose) {
200211
if self.ime_state != Some((position, purpose)) {
201212
self.ime_state = Some((position, purpose));
202213
}

layershellev/src/lib.rs

Lines changed: 10 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -767,22 +767,6 @@ impl<T> WindowState<T> {
767767
}
768768

769769
impl<T> WindowState<T> {
770-
/// gen the wrapper for the main window
771-
/// if there is none, it will create a fake wrapper
772-
/// used to get display and etc
773-
/// It is not suggested to use this one, We will remove this one in next version
774-
#[deprecated(note = "use gen_mainwindow_wrapper instead")]
775-
pub fn gen_main_wrapper(&self) -> WindowWrapper {
776-
if self.is_background() {
777-
return WindowWrapper {
778-
id: id::Id::MAIN,
779-
display: self.display.as_ref().unwrap().clone(),
780-
wl_surface: self.background_surface.as_ref().unwrap().clone(),
781-
viewport: None,
782-
};
783-
}
784-
self.main_window().gen_wrapper()
785-
}
786770
/// gen the wrapper to the main window
787771
/// used to get display and etc
788772
pub fn gen_mainwindow_wrapper(&self) -> WindowWrapper {
@@ -822,6 +806,15 @@ impl<T> WindowState<T> {
822806
}
823807
}
824808

809+
/// In case when the focused surface is not the request surface, but it is still be disabled
810+
/// So this time, we need to use a id to ensure this won't happen
811+
pub fn set_ime_allowed_with_id(&mut self, ime_allowed: bool, id: id::Id) {
812+
if self.current_surface_id().is_none_or(|cid| cid != id) {
813+
return;
814+
}
815+
self.set_ime_allowed(ime_allowed);
816+
}
817+
825818
// TODO: maybe I should put text_inputs to unit
826819
pub fn set_ime_cursor_area<P: Into<dpi::Position>, S: Into<dpi::Size>>(
827820
&self,
@@ -1735,6 +1728,7 @@ impl<T> Dispatch<xdg_surface::XdgSurface, ()> for WindowState<T> {
17351728
}
17361729
}
17371730
}
1731+
17381732
impl<T> Dispatch<zwlr_layer_surface_v1::ZwlrLayerSurfaceV1, ()> for WindowState<T> {
17391733
fn event(
17401734
state: &mut Self,

0 commit comments

Comments
 (0)