Skip to content

Commit 95412a8

Browse files
committed
chore: almost finished
1 parent 1f94478 commit 95412a8

File tree

3 files changed

+115
-7
lines changed

3 files changed

+115
-7
lines changed

iced_layershell/src/actions.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,9 @@ pub(crate) enum LayerShellAction {
1616
CustomActionsWithId(LayershellCustomActionsWithIdInner),
1717
RedrawAll,
1818
RedrawWindow(LayerId), // maybe one day it is useful, but now useless
19-
NewMenu((IcedNewPopupSettings, iced_core::window::Id)),
20-
Ime(input_method::InputMethod)
19+
NewMenu(IcedNewPopupSettings, iced_core::window::Id),
20+
Ime(input_method::InputMethod),
21+
ImeWithId(LayerId, input_method::InputMethod)
2122
}
2223

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

iced_layershell/src/multi_window.rs

Lines changed: 37 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -467,7 +467,26 @@ where
467467
}
468468
}
469469
}
470-
LayerShellAction::NewMenu((menusettings, info)) => 'out: {
470+
LayerShellAction::ImeWithId(id, ime) => match ime{
471+
iced_core::InputMethod::Disabled => {
472+
ev.set_ime_allowed(false);
473+
}
474+
iced_core::InputMethod::Enabled {
475+
position, purpose, ..
476+
} => {
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+
);
487+
}
488+
},
489+
LayerShellAction::NewMenu(menusettings, info) => 'out: {
471490
let IcedNewPopupSettings { size, position } = menusettings;
472491
let Some(id) = ev.current_surface_id() else {
473492
break 'out;
@@ -578,7 +597,7 @@ async fn run_instance<A, E, C>(
578597
});
579598
match event {
580599
MultiWindowIcedLayerEvent(
581-
_id,
600+
oid,
582601
IcedLayerEvent::RequestRefreshWithWrapper {
583602
width,
584603
height,
@@ -660,14 +679,27 @@ async fn run_instance<A, E, C>(
660679
let cursor = window.state.cursor();
661680

662681
events.push((Some(id), redraw_event.clone()));
663-
ui.update(
682+
let (ui_state, _) = ui.update(
664683
&[redraw_event.clone()],
665684
cursor,
666685
&mut window.renderer,
667686
&mut clipboard,
668687
&mut messages,
669688
);
689+
if let user_interface::State::Updated {
690+
redraw_request: _, // NOTE: I do not know how to use it now
691+
input_method,
692+
} = ui_state
693+
{
694+
events.push((Some(id), redraw_event.clone()));
695+
custom_actions.push(LayerShellAction::ImeWithId(
696+
oid.unwrap(),
697+
input_method.clone(),
698+
));
699+
window.request_input_method(input_method);
700+
}
670701

702+
window.draw_preedit();
671703
debug.draw_started();
672704
let new_mouse_interaction = ui.draw(
673705
&mut window.renderer,
@@ -934,13 +966,13 @@ async fn run_instance<A, E, C>(
934966
if let MenuDirection::Up = direction {
935967
y -= height as i32;
936968
}
937-
custom_actions.push(LayerShellAction::NewMenu((
969+
custom_actions.push(LayerShellAction::NewMenu(
938970
IcedNewPopupSettings {
939971
size: (width, height),
940972
position: (x, y),
941973
},
942974
info,
943-
)));
975+
));
944976
}
945977
_ => {}
946978
}

iced_layershell/src/multi_window/window_manager.rs

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@ use std::{collections::BTreeMap, sync::Arc};
22

33
use super::state::State;
44
use crate::DefaultStyle;
5+
use crate::ime_preedit::Preedit;
56
use crate::multi_window::Application;
7+
use iced_core::InputMethod;
8+
use iced_core::input_method;
69
use iced_graphics::Compositor;
710
use layershellev::{WindowWrapper, id::Id as LayerId};
811

@@ -20,6 +23,8 @@ where
2023
pub surface: C::Surface,
2124
pub state: State<A>,
2225
pub mouse_interaction: mouse::Interaction,
26+
preedit: Option<Preedit<A::Renderer>>,
27+
ime_state: Option<(iced_core::Point, input_method::Purpose)>,
2328
}
2429

2530
pub struct WindowManager<A: Application, C: Compositor>
@@ -95,6 +100,8 @@ where
95100
surface,
96101
state,
97102
mouse_interaction: mouse::Interaction::Idle,
103+
preedit: None,
104+
ime_state: None,
98105
},
99106
);
100107
self.entries
@@ -135,3 +142,71 @@ where
135142
self.entries.get(&id)
136143
}
137144
}
145+
146+
impl<A, C> Window<A, C>
147+
where
148+
A: Application,
149+
C: Compositor<Renderer = A::Renderer>,
150+
A::Theme: DefaultStyle,
151+
{
152+
pub fn request_input_method(&mut self, input_method: InputMethod) {
153+
match input_method {
154+
InputMethod::Disabled => {
155+
self.disable_ime();
156+
}
157+
InputMethod::Enabled {
158+
position,
159+
purpose,
160+
preedit,
161+
} => {
162+
self.enable_ime(position, purpose);
163+
164+
if let Some(preedit) = preedit {
165+
if preedit.content.is_empty() {
166+
self.preedit = None;
167+
} else {
168+
let mut overlay = self.preedit.take().unwrap_or_else(Preedit::new);
169+
170+
overlay.update(
171+
position,
172+
&preedit,
173+
self.state.background_color(),
174+
&self.renderer,
175+
);
176+
177+
self.preedit = Some(overlay);
178+
}
179+
} else {
180+
self.preedit = None;
181+
}
182+
}
183+
}
184+
}
185+
186+
pub fn draw_preedit(&mut self) {
187+
use iced_core::Point;
188+
use iced_core::Rectangle;
189+
if let Some(preedit) = &self.preedit {
190+
preedit.draw(
191+
&mut self.renderer,
192+
self.state.text_color(),
193+
self.state.background_color(),
194+
&Rectangle::new(Point::ORIGIN, self.state.viewport().logical_size()),
195+
);
196+
}
197+
}
198+
199+
fn enable_ime(&mut self, position: iced_core::Point, purpose: input_method::Purpose) {
200+
if self.ime_state != Some((position, purpose)) {
201+
self.ime_state = Some((position, purpose));
202+
}
203+
}
204+
205+
fn disable_ime(&mut self) {
206+
if self.ime_state.is_some() {
207+
self.ime_state = None;
208+
}
209+
210+
self.preedit = None;
211+
}
212+
}

0 commit comments

Comments
 (0)