1
0
mirror of https://github.com/emilk/egui.git synced 2026-09-02 06:40:06 -04:00

Add ViewportCommand::RequestCut, RequestCopy and RequestPaste to trigger Clipboard actions (#4035)

### Motivation
We want to offer our users a context menu with `Cut`, `Copy` and `Paste`
actions. `Paste` is not possible out of the box.

### Changes
This PR adds `ViewportCommand::RequestCut`,
`ViewportCommand::RequestCopy` and `ViewportCommand::RequestPaste`. They
are routed and handled after the example of
`ViewportCommand::Screenshot` and result in the same code being executed
as when the user uses `CTRL+V` style keyboard commands.

### Reasoning
In our last release we used an instance of
`egui_winit:📋:Clipboard` in order to get the `Paste`
functionality.

However Linux users on Wayland complained about broken clipboard
interaction (https://github.com/mikedilger/gossip/issues/617). After a
while of digging I could not find the issue although I have found
references to problems with multiple clipboards per handle before
(https://gitlab.gnome.org/GNOME/mutter/-/issues/1250) but I compared
mutter with weston and the problem occured on both.

So to solve this I set out to extend egui to access the clipboard
instance already present in egui_winit. Since there was no trivial way
to reach the instance of `egui_winit::State` I felt the best approach
was to follow the logic of the new `ViewportCommand::Screenshot`.

### Variations
It could make sense to make the introduced `enum ActionRequested` a part
of crates/egui/src/viewport.rs and to then wrap them into one single
`ViewportCommand::ActionRequest(ActionRequested)`.

### Example
```Rust
let mut text = String::new();
let response = ui.text_edit_singleline(&mut text);
if ui.button("Paste").clicked() {
    response.request_focus();
    ui.ctx().send_viewport_cmd(ViewportCommand::RequestPaste);
}
```

---------

Co-authored-by: Emil Ernerfeldt <emil.ernerfeldt@gmail.com>
This commit is contained in:
bu5hm4nn
2024-04-22 01:06:33 -06:00
committed by GitHub
parent 87b294534e
commit a2f1ca31a0
5 changed files with 119 additions and 34 deletions

View File

@@ -14,7 +14,9 @@ pub use accesskit_winit;
pub use egui;
#[cfg(feature = "accesskit")]
use egui::accesskit;
use egui::{Pos2, Rect, Vec2, ViewportBuilder, ViewportCommand, ViewportId, ViewportInfo};
use egui::{
ahash::HashSet, Pos2, Rect, Vec2, ViewportBuilder, ViewportCommand, ViewportId, ViewportInfo,
};
pub use winit;
pub mod clipboard;
@@ -1254,6 +1256,13 @@ fn translate_cursor(cursor_icon: egui::CursorIcon) -> Option<winit::window::Curs
// Helpers for egui Viewports
// ---------------------------------------------------------------------------
#[derive(PartialEq, Eq, Hash, Debug)]
pub enum ActionRequested {
Screenshot,
Cut,
Copy,
Paste,
}
pub fn process_viewport_commands(
egui_ctx: &egui::Context,
@@ -1261,7 +1270,7 @@ pub fn process_viewport_commands(
commands: impl IntoIterator<Item = ViewportCommand>,
window: &Window,
is_viewport_focused: bool,
screenshot_requested: &mut bool,
actions_requested: &mut HashSet<ActionRequested>,
) {
for command in commands {
process_viewport_command(
@@ -1270,7 +1279,7 @@ pub fn process_viewport_commands(
command,
info,
is_viewport_focused,
screenshot_requested,
actions_requested,
);
}
}
@@ -1281,7 +1290,7 @@ fn process_viewport_command(
command: ViewportCommand,
info: &mut ViewportInfo,
is_viewport_focused: bool,
screenshot_requested: &mut bool,
actions_requested: &mut HashSet<ActionRequested>,
) {
crate::profile_function!();
@@ -1478,7 +1487,16 @@ fn process_viewport_command(
}
}
ViewportCommand::Screenshot => {
*screenshot_requested = true;
actions_requested.insert(ActionRequested::Screenshot);
}
ViewportCommand::RequestCut => {
actions_requested.insert(ActionRequested::Cut);
}
ViewportCommand::RequestCopy => {
actions_requested.insert(ActionRequested::Copy);
}
ViewportCommand::RequestPaste => {
actions_requested.insert(ActionRequested::Paste);
}
}
}