fix: give clipboard/primary TARGETS unique atoms
The clipboard and primary selections previously used the same atom to store TARGETS when queried for them by `handle_target_list`. When a program requests both selections simultaneously, problems such as one selection using the target list of the other, then deleting it and requiring the second target to get the selection targets again could occur. This was observed when using `wl-clip-persist` and could result in selection desyncs. This change gives a unique atom to each primary and clipboard selection targets so they no longer compete over the same property. It also adds updates to the `copy_from_x11` intergration to test for this issue.
This commit is contained in:
parent
3cd3edffe1
commit
34bf07db05
3 changed files with 70 additions and 41 deletions
|
|
@ -998,15 +998,16 @@ xcb::atoms_struct! {
|
|||
motif_wm_hints => b"_MOTIF_WM_HINTS" only_if_exists = false,
|
||||
utf8_string => b"UTF8_STRING" only_if_exists = false,
|
||||
clipboard => b"CLIPBOARD" only_if_exists = false,
|
||||
clipboard_targets => b"_clipboard_targets" only_if_exists = false,
|
||||
targets => b"TARGETS" only_if_exists = false,
|
||||
save_targets => b"SAVE_TARGETS" only_if_exists = false,
|
||||
multiple => b"MULTIPLE" only_if_exists = false,
|
||||
timestamp => b"TIMESTAMP" only_if_exists = false,
|
||||
selection_reply => b"_selection_reply" only_if_exists = false,
|
||||
incr => b"INCR" only_if_exists = false,
|
||||
xsettings => b"_XSETTINGS_S0" only_if_exists = false,
|
||||
xsettings_settings => b"_XSETTINGS_SETTINGS" only_if_exists = false,
|
||||
primary => b"PRIMARY" only_if_exists = false,
|
||||
primary_targets => b"_primary_targets" only_if_exists = false,
|
||||
moveresize => b"_NET_WM_MOVERESIZE" only_if_exists = false,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -233,6 +233,7 @@ enum CurrentSelection<T: SelectionType> {
|
|||
struct SelectionData<T: SelectionType> {
|
||||
last_selection_timestamp: u32,
|
||||
atom: x::Atom,
|
||||
targets_atom: x::Atom,
|
||||
current_selection: Option<CurrentSelection<T>>,
|
||||
}
|
||||
|
||||
|
|
@ -269,10 +270,11 @@ trait SelectionDataImpl {
|
|||
}
|
||||
|
||||
impl<T: SelectionType> SelectionData<T> {
|
||||
fn new(atom: x::Atom) -> Self {
|
||||
fn new(atom: x::Atom, targets_atom: x::Atom) -> Self {
|
||||
Self {
|
||||
last_selection_timestamp: x::CURRENT_TIME,
|
||||
atom,
|
||||
targets_atom,
|
||||
current_selection: None,
|
||||
}
|
||||
}
|
||||
|
|
@ -336,7 +338,7 @@ impl<T: SelectionType> SelectionDataImpl for SelectionData<T> {
|
|||
requestor: wm_window,
|
||||
selection: self.atom,
|
||||
target: atoms.targets,
|
||||
property: atoms.selection_reply,
|
||||
property: self.targets_atom,
|
||||
time: timestamp,
|
||||
}) {
|
||||
Ok(_) => {
|
||||
|
|
@ -571,8 +573,8 @@ impl SelectionState {
|
|||
.expect("Couldn't create window for selections");
|
||||
Self {
|
||||
target_window,
|
||||
clipboard: SelectionData::new(atoms.clipboard),
|
||||
primary: SelectionData::new(atoms.primary),
|
||||
clipboard: SelectionData::new(atoms.clipboard, atoms.clipboard_targets),
|
||||
primary: SelectionData::new(atoms.primary, atoms.primary_targets),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue