xwayland: Delay selection notify until focused
This commit is contained in:
parent
b5e60fcde5
commit
087ebaa2c7
2 changed files with 63 additions and 9 deletions
|
|
@ -18,19 +18,42 @@ impl SelectionHandler for State {
|
||||||
source: Option<SelectionSource>,
|
source: Option<SelectionSource>,
|
||||||
_seat: Seat<State>,
|
_seat: Seat<State>,
|
||||||
) {
|
) {
|
||||||
if let Some(xwm) = self
|
let Some(xwm_id) = self
|
||||||
.common
|
.common
|
||||||
.xwayland_state
|
.xwayland_state
|
||||||
.as_mut()
|
.as_ref()
|
||||||
.and_then(|xstate| xstate.xwm.as_mut())
|
.and_then(|xstate| xstate.xwm.as_ref())
|
||||||
{
|
.map(|xwm| xwm.id())
|
||||||
if let Some(source) = &source {
|
else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
let x_has_focus = self.common.has_x_keyboard_focus(xwm_id);
|
||||||
|
|
||||||
|
let xstate = self.common.xwayland_state.as_mut().unwrap();
|
||||||
|
let xwm = xstate.xwm.as_mut().unwrap();
|
||||||
|
|
||||||
|
if let Some(source) = &source {
|
||||||
|
if x_has_focus {
|
||||||
if let Err(err) = xwm.new_selection(target, Some(source.mime_types())) {
|
if let Err(err) = xwm.new_selection(target, Some(source.mime_types())) {
|
||||||
warn!(?err, "Failed to set Xwayland clipboard selection.");
|
warn!(?err, "Failed to set Xwayland clipboard selection.");
|
||||||
}
|
}
|
||||||
} else if let Err(err) = xwm.new_selection(target, None) {
|
} else {
|
||||||
|
match target {
|
||||||
|
SelectionTarget::Clipboard => {
|
||||||
|
xstate.clipboard_selection_dirty = Some(source.mime_types())
|
||||||
|
}
|
||||||
|
SelectionTarget::Primary => {
|
||||||
|
xstate.primary_selection_dirty = Some(source.mime_types())
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if let Err(err) = xwm.new_selection(target, None) {
|
||||||
warn!(?err, "Failed to clear Xwayland selection.");
|
warn!(?err, "Failed to clear Xwayland selection.");
|
||||||
}
|
}
|
||||||
|
xstate.clipboard_selection_dirty = None;
|
||||||
|
xstate.primary_selection_dirty = None;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -64,6 +64,8 @@ pub struct XWaylandState {
|
||||||
pub pressed_keys: Vec<Keycode>,
|
pub pressed_keys: Vec<Keycode>,
|
||||||
pub pressed_buttons: Vec<u32>,
|
pub pressed_buttons: Vec<u32>,
|
||||||
pub last_modifier_state: Option<ModifiersState>,
|
pub last_modifier_state: Option<ModifiersState>,
|
||||||
|
pub clipboard_selection_dirty: Option<Vec<String>>,
|
||||||
|
pub primary_selection_dirty: Option<Vec<String>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl State {
|
impl State {
|
||||||
|
|
@ -108,6 +110,8 @@ impl State {
|
||||||
pressed_keys: Vec::new(),
|
pressed_keys: Vec::new(),
|
||||||
pressed_buttons: Vec::new(),
|
pressed_buttons: Vec::new(),
|
||||||
last_modifier_state: None,
|
last_modifier_state: None,
|
||||||
|
clipboard_selection_dirty: None,
|
||||||
|
primary_selection_dirty: None,
|
||||||
});
|
});
|
||||||
|
|
||||||
let wm = match X11Wm::start_wm(
|
let wm = match X11Wm::start_wm(
|
||||||
|
|
@ -244,7 +248,7 @@ impl XWaylandState {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Common {
|
impl Common {
|
||||||
fn has_x_keyboard_focus(&self, xwmid: XwmId) -> bool {
|
pub fn has_x_keyboard_focus(&self, xwmid: XwmId) -> bool {
|
||||||
let keyboard = self
|
let keyboard = self
|
||||||
.shell
|
.shell
|
||||||
.read()
|
.read()
|
||||||
|
|
@ -290,10 +294,37 @@ impl Common {
|
||||||
if target
|
if target
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.is_some_and(|target| matches!(target, KeyboardFocusTarget::LockSurface(_)))
|
.is_some_and(|target| matches!(target, KeyboardFocusTarget::LockSurface(_)))
|
||||||
|| (!self.has_x_keyboard_focus(xwm_id)
|
|
||||||
&& target.as_ref().is_some_and(|target| target.is_xwm(xwm_id)))
|
|
||||||
{
|
{
|
||||||
self.xwayland_reset_eavesdropping(serial);
|
self.xwayland_reset_eavesdropping(serial);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if !self.has_x_keyboard_focus(xwm_id)
|
||||||
|
&& target.as_ref().is_some_and(|target| target.is_xwm(xwm_id))
|
||||||
|
{
|
||||||
|
self.xwayland_reset_eavesdropping(serial);
|
||||||
|
|
||||||
|
let xstate = self.xwayland_state.as_mut().unwrap();
|
||||||
|
if let Some(mime_types) = xstate.clipboard_selection_dirty.take() {
|
||||||
|
if let Err(err) = xstate
|
||||||
|
.xwm
|
||||||
|
.as_mut()
|
||||||
|
.unwrap()
|
||||||
|
.new_selection(SelectionTarget::Clipboard, Some(mime_types))
|
||||||
|
{
|
||||||
|
warn!(?err, "Failed to set Xwayland clipboard selection.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if let Some(mime_types) = xstate.primary_selection_dirty.take() {
|
||||||
|
if let Err(err) = xstate
|
||||||
|
.xwm
|
||||||
|
.as_mut()
|
||||||
|
.unwrap()
|
||||||
|
.new_selection(SelectionTarget::Primary, Some(mime_types))
|
||||||
|
{
|
||||||
|
warn!(?err, "Failed to set Xwayland clipboard selection.");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue