Merge pull request #1613 from FreddyFunk/feat/clipboard-paste-menu-graying
feat: gray out paste menu when clipboard is empty or location unsupported
This commit is contained in:
commit
4e0b44b5bb
5 changed files with 173 additions and 20 deletions
126
src/app.rs
126
src/app.rs
|
|
@ -73,8 +73,8 @@ use wayland_client::{Proxy, protocol::wl_output::WlOutput};
|
||||||
use crate::{
|
use crate::{
|
||||||
FxOrderMap,
|
FxOrderMap,
|
||||||
clipboard::{
|
clipboard::{
|
||||||
ClipboardCopy, ClipboardKind, ClipboardPaste, ClipboardPasteImage, ClipboardPasteText,
|
ClipboardCache, ClipboardCopy, ClipboardKind, ClipboardPaste, ClipboardPasteImage,
|
||||||
ClipboardPasteVideo,
|
ClipboardPasteText, ClipboardPasteVideo,
|
||||||
},
|
},
|
||||||
config::{
|
config::{
|
||||||
AppTheme, Config, DesktopConfig, Favorite, IconSizes, State, TIME_CONFIG_ID, TabConfig,
|
AppTheme, Config, DesktopConfig, Favorite, IconSizes, State, TIME_CONFIG_ID, TabConfig,
|
||||||
|
|
@ -407,6 +407,11 @@ pub enum Message {
|
||||||
PasteTextContents(PathBuf, ClipboardPasteText),
|
PasteTextContents(PathBuf, ClipboardPasteText),
|
||||||
PasteVideo(PathBuf),
|
PasteVideo(PathBuf),
|
||||||
PasteVideoContents(PathBuf, ClipboardPasteVideo),
|
PasteVideoContents(PathBuf, ClipboardPasteVideo),
|
||||||
|
CheckClipboard,
|
||||||
|
CheckClipboardImage,
|
||||||
|
CheckClipboardVideo,
|
||||||
|
CheckClipboardText,
|
||||||
|
ClipboardCached(ClipboardCache),
|
||||||
PendingCancel(u64),
|
PendingCancel(u64),
|
||||||
PendingCancelAll,
|
PendingCancelAll,
|
||||||
PendingComplete(u64, OperationSelection),
|
PendingComplete(u64, OperationSelection),
|
||||||
|
|
@ -761,9 +766,15 @@ pub struct App {
|
||||||
tab_drag_id: DragId,
|
tab_drag_id: DragId,
|
||||||
auto_scroll_speed: Option<i16>,
|
auto_scroll_speed: Option<i16>,
|
||||||
file_dialog_opt: Option<Dialog<Message>>,
|
file_dialog_opt: Option<Dialog<Message>>,
|
||||||
|
clipboard_cache: ClipboardCache,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl App {
|
impl App {
|
||||||
|
/// Returns true if the clipboard cache contains pasteable content
|
||||||
|
fn clipboard_has_content(&self) -> bool {
|
||||||
|
!matches!(self.clipboard_cache, ClipboardCache::Empty)
|
||||||
|
}
|
||||||
|
|
||||||
fn push_dialog(&mut self, page: DialogPage, focus_id: Option<widget::Id>) -> Task<Message> {
|
fn push_dialog(&mut self, page: DialogPage, focus_id: Option<widget::Id>) -> Task<Message> {
|
||||||
let t = self.dialog_pages.push_back(page);
|
let t = self.dialog_pages.push_back(page);
|
||||||
if let Some(focus_id) = focus_id {
|
if let Some(focus_id) = focus_id {
|
||||||
|
|
@ -2311,11 +2322,12 @@ impl Application for App {
|
||||||
tab_drag_id: DragId::new(),
|
tab_drag_id: DragId::new(),
|
||||||
auto_scroll_speed: None,
|
auto_scroll_speed: None,
|
||||||
file_dialog_opt: None,
|
file_dialog_opt: None,
|
||||||
|
clipboard_cache: ClipboardCache::Empty,
|
||||||
#[cfg(all(feature = "wayland", feature = "desktop-applet"))]
|
#[cfg(all(feature = "wayland", feature = "desktop-applet"))]
|
||||||
layer_sizes: FxHashMap::default(),
|
layer_sizes: FxHashMap::default(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut commands = vec![app.update_config()];
|
let mut commands = vec![app.update_config(), app.update(Message::CheckClipboard)];
|
||||||
|
|
||||||
for location in flags.locations {
|
for location in flags.locations {
|
||||||
if let Some(path) = location.path_opt()
|
if let Some(path) = location.path_opt()
|
||||||
|
|
@ -3658,15 +3670,39 @@ impl Application for App {
|
||||||
&& let Some(path) = tab.location.path_opt()
|
&& let Some(path) = tab.location.path_opt()
|
||||||
{
|
{
|
||||||
let to = path.clone();
|
let to = path.clone();
|
||||||
return clipboard::read_data::<ClipboardPaste>().map(move |contents_opt| {
|
|
||||||
match contents_opt {
|
// Use cached clipboard data if available (needed for Wayland popups)
|
||||||
Some(contents) => {
|
match &self.clipboard_cache {
|
||||||
cosmic::action::app(Message::PasteContents(to.clone(), contents))
|
ClipboardCache::Files(contents) => {
|
||||||
}
|
return self
|
||||||
// No file data in clipboard, try image data
|
.update(Message::PasteContents(to.clone(), contents.clone()));
|
||||||
None => cosmic::action::app(Message::PasteImage(to.clone())),
|
|
||||||
}
|
}
|
||||||
});
|
ClipboardCache::Image(contents) => {
|
||||||
|
return self
|
||||||
|
.update(Message::PasteImageContents(to.clone(), contents.clone()));
|
||||||
|
}
|
||||||
|
ClipboardCache::Video(contents) => {
|
||||||
|
return self
|
||||||
|
.update(Message::PasteVideoContents(to.clone(), contents.clone()));
|
||||||
|
}
|
||||||
|
ClipboardCache::Text(contents) => {
|
||||||
|
return self
|
||||||
|
.update(Message::PasteTextContents(to.clone(), contents.clone()));
|
||||||
|
}
|
||||||
|
ClipboardCache::Empty => {
|
||||||
|
// Cache is empty, try reading from clipboard directly
|
||||||
|
// (works when triggered from main window, e.g., Ctrl+V)
|
||||||
|
return clipboard::read_data::<ClipboardPaste>().map(
|
||||||
|
move |contents_opt| match contents_opt {
|
||||||
|
Some(contents) => cosmic::action::app(Message::PasteContents(
|
||||||
|
to.clone(),
|
||||||
|
contents,
|
||||||
|
)),
|
||||||
|
None => cosmic::action::app(Message::PasteImage(to.clone())),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Message::PasteContents(to, mut contents) => {
|
Message::PasteContents(to, mut contents) => {
|
||||||
|
|
@ -3781,6 +3817,48 @@ impl Application for App {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Message::CheckClipboard => {
|
||||||
|
// Check if clipboard has any paste-able content and cache it
|
||||||
|
return clipboard::read_data::<ClipboardPaste>().map(|contents_opt| {
|
||||||
|
match contents_opt {
|
||||||
|
Some(contents) => cosmic::action::app(Message::ClipboardCached(
|
||||||
|
ClipboardCache::Files(contents),
|
||||||
|
)),
|
||||||
|
None => cosmic::action::app(Message::CheckClipboardImage),
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
Message::CheckClipboardImage => {
|
||||||
|
return clipboard::read_data::<ClipboardPasteImage>().map(|contents_opt| {
|
||||||
|
match contents_opt {
|
||||||
|
Some(contents) => cosmic::action::app(Message::ClipboardCached(
|
||||||
|
ClipboardCache::Image(contents),
|
||||||
|
)),
|
||||||
|
None => cosmic::action::app(Message::CheckClipboardVideo),
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
Message::CheckClipboardVideo => {
|
||||||
|
return clipboard::read_data::<ClipboardPasteVideo>().map(|contents_opt| {
|
||||||
|
match contents_opt {
|
||||||
|
Some(contents) => cosmic::action::app(Message::ClipboardCached(
|
||||||
|
ClipboardCache::Video(contents),
|
||||||
|
)),
|
||||||
|
None => cosmic::action::app(Message::CheckClipboardText),
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
Message::CheckClipboardText => {
|
||||||
|
return clipboard::read_data::<ClipboardPasteText>().map(|contents_opt| {
|
||||||
|
cosmic::action::app(Message::ClipboardCached(match contents_opt {
|
||||||
|
Some(contents) => ClipboardCache::Text(contents),
|
||||||
|
None => ClipboardCache::Empty,
|
||||||
|
}))
|
||||||
|
});
|
||||||
|
}
|
||||||
|
Message::ClipboardCached(cache) => {
|
||||||
|
self.clipboard_cache = cache;
|
||||||
|
}
|
||||||
Message::PendingCancel(id) => {
|
Message::PendingCancel(id) => {
|
||||||
if let Some((_, controller)) = self.pending_operations.get(&id) {
|
if let Some((_, controller)) = self.pending_operations.get(&id) {
|
||||||
controller.cancel();
|
controller.cancel();
|
||||||
|
|
@ -5042,6 +5120,8 @@ impl Application for App {
|
||||||
_ => {}
|
_ => {}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
// Check clipboard when window gains focus
|
||||||
|
return self.update(Message::CheckClipboard);
|
||||||
}
|
}
|
||||||
Message::Surface(action) => {
|
Message::Surface(action) => {
|
||||||
return cosmic::task::message(cosmic::Action::Cosmic(
|
return cosmic::task::message(cosmic::Action::Cosmic(
|
||||||
|
|
@ -5996,6 +6076,7 @@ impl Application for App {
|
||||||
&self.config,
|
&self.config,
|
||||||
&self.modifiers,
|
&self.modifiers,
|
||||||
&self.key_binds,
|
&self.key_binds,
|
||||||
|
self.clipboard_has_content(),
|
||||||
)]
|
)]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -6084,7 +6165,11 @@ impl Application for App {
|
||||||
let entity = self.tab_model.active();
|
let entity = self.tab_model.active();
|
||||||
if let Some(tab) = self.tab_model.data::<Tab>(entity) {
|
if let Some(tab) = self.tab_model.data::<Tab>(entity) {
|
||||||
let tab_view = tab
|
let tab_view = tab
|
||||||
.view(&self.key_binds, &self.modifiers)
|
.view(
|
||||||
|
&self.key_binds,
|
||||||
|
&self.modifiers,
|
||||||
|
self.clipboard_has_content(),
|
||||||
|
)
|
||||||
.map(move |message| Message::TabMessage(Some(entity), message));
|
.map(move |message| Message::TabMessage(Some(entity), message));
|
||||||
tab_column = tab_column.push(tab_view);
|
tab_column = tab_column.push(tab_view);
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -6107,8 +6192,13 @@ impl Application for App {
|
||||||
WindowKind::ContextMenu(entity, id) => match self.tab_model.data::<Tab>(*entity) {
|
WindowKind::ContextMenu(entity, id) => match self.tab_model.data::<Tab>(*entity) {
|
||||||
Some(tab) => {
|
Some(tab) => {
|
||||||
return widget::autosize::autosize(
|
return widget::autosize::autosize(
|
||||||
menu::context_menu(tab, &self.key_binds, &window.modifiers)
|
menu::context_menu(
|
||||||
.map(|x| Message::TabMessage(Some(*entity), x)),
|
tab,
|
||||||
|
&self.key_binds,
|
||||||
|
&window.modifiers,
|
||||||
|
self.clipboard_has_content(),
|
||||||
|
)
|
||||||
|
.map(|x| Message::TabMessage(Some(*entity), x)),
|
||||||
id.clone(),
|
id.clone(),
|
||||||
)
|
)
|
||||||
.into();
|
.into();
|
||||||
|
|
@ -6120,7 +6210,11 @@ impl Application for App {
|
||||||
|
|
||||||
let tab_view = match self.tab_model.data::<Tab>(*entity) {
|
let tab_view = match self.tab_model.data::<Tab>(*entity) {
|
||||||
Some(tab) => tab
|
Some(tab) => tab
|
||||||
.view(&self.key_binds, &window.modifiers)
|
.view(
|
||||||
|
&self.key_binds,
|
||||||
|
&window.modifiers,
|
||||||
|
self.clipboard_has_content(),
|
||||||
|
)
|
||||||
.map(move |message| Message::TabMessage(Some(*entity), message)),
|
.map(move |message| Message::TabMessage(Some(*entity), message)),
|
||||||
None => widget::vertical_space().into(),
|
None => widget::vertical_space().into(),
|
||||||
};
|
};
|
||||||
|
|
@ -6221,6 +6315,8 @@ impl Application for App {
|
||||||
}
|
}
|
||||||
#[cfg(all(feature = "wayland", feature = "desktop-applet"))]
|
#[cfg(all(feature = "wayland", feature = "desktop-applet"))]
|
||||||
Event::Window(WindowEvent::Focused) => Some(Message::Focused(window_id)),
|
Event::Window(WindowEvent::Focused) => Some(Message::Focused(window_id)),
|
||||||
|
#[cfg(not(all(feature = "wayland", feature = "desktop-applet")))]
|
||||||
|
Event::Window(WindowEvent::Focused) => Some(Message::CheckClipboard),
|
||||||
Event::Window(WindowEvent::CloseRequested) => Some(Message::WindowClose),
|
Event::Window(WindowEvent::CloseRequested) => Some(Message::WindowClose),
|
||||||
Event::Window(WindowEvent::Opened { position: _, size }) => {
|
Event::Window(WindowEvent::Opened { position: _, size }) => {
|
||||||
Some(Message::Size(window_id, size))
|
Some(Message::Size(window_id, size))
|
||||||
|
|
|
||||||
|
|
@ -325,3 +325,14 @@ impl TryFrom<(Vec<u8>, String)> for ClipboardPasteText {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Cached clipboard content for paste operations.
|
||||||
|
/// This is needed because Wayland restricts clipboard access from popup windows.
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
pub enum ClipboardCache {
|
||||||
|
Files(ClipboardPaste),
|
||||||
|
Image(ClipboardPasteImage),
|
||||||
|
Video(ClipboardPasteVideo),
|
||||||
|
Text(ClipboardPasteText),
|
||||||
|
Empty,
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1804,6 +1804,7 @@ impl Application for App {
|
||||||
&app.tab,
|
&app.tab,
|
||||||
&app.key_binds,
|
&app.key_binds,
|
||||||
&app.modifiers,
|
&app.modifiers,
|
||||||
|
false, // Paste not used in dialogs
|
||||||
)
|
)
|
||||||
.map(Message::TabMessage)
|
.map(Message::TabMessage)
|
||||||
.map(cosmic::Action::App),
|
.map(cosmic::Action::App),
|
||||||
|
|
@ -1988,7 +1989,7 @@ impl Application for App {
|
||||||
|
|
||||||
col = col.push(
|
col = col.push(
|
||||||
self.tab
|
self.tab
|
||||||
.view(&self.key_binds, &self.modifiers)
|
.view(&self.key_binds, &self.modifiers, false)
|
||||||
.map(Message::TabMessage),
|
.map(Message::TabMessage),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
||||||
31
src/menu.rs
31
src/menu.rs
|
|
@ -59,6 +59,7 @@ pub fn context_menu<'a>(
|
||||||
tab: &Tab,
|
tab: &Tab,
|
||||||
key_binds: &HashMap<KeyBind, Action>,
|
key_binds: &HashMap<KeyBind, Action>,
|
||||||
modifiers: &Modifiers,
|
modifiers: &Modifiers,
|
||||||
|
clipboard_paste_available: bool,
|
||||||
) -> Element<'a, tab::Message> {
|
) -> Element<'a, tab::Message> {
|
||||||
let find_key = |action: &Action| -> String {
|
let find_key = |action: &Action| -> String {
|
||||||
for (key_bind, key_action) in key_binds {
|
for (key_bind, key_action) in key_binds {
|
||||||
|
|
@ -75,6 +76,13 @@ pub fn context_menu<'a>(
|
||||||
color: Some(color.into()),
|
color: Some(color.into()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
fn disabled_style(theme: &cosmic::Theme) -> TextStyle {
|
||||||
|
let mut color = theme.cosmic().background.component.on;
|
||||||
|
color.alpha *= 0.5;
|
||||||
|
TextStyle {
|
||||||
|
color: Some(color.into()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let menu_item = |label, action| {
|
let menu_item = |label, action| {
|
||||||
let key = find_key(&action);
|
let key = find_key(&action);
|
||||||
|
|
@ -86,6 +94,18 @@ pub fn context_menu<'a>(
|
||||||
.on_press(tab::Message::ContextAction(action))
|
.on_press(tab::Message::ContextAction(action))
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let menu_item_disabled = |label, action: Action| {
|
||||||
|
let key = find_key(&action);
|
||||||
|
menu_button!(
|
||||||
|
text::body(label).class(theme::Text::Custom(disabled_style)),
|
||||||
|
horizontal_space(),
|
||||||
|
text::body(key).class(theme::Text::Custom(disabled_style))
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
|
// Allow paste when clipboard has data and we're in a location that supports it
|
||||||
|
let can_paste = clipboard_paste_available && tab.location.supports_paste();
|
||||||
|
|
||||||
let (sort_name, sort_direction, _) = tab.sort_options();
|
let (sort_name, sort_direction, _) = tab.sort_options();
|
||||||
let sort_item = |label, variant| {
|
let sort_item = |label, variant| {
|
||||||
menu_item(
|
menu_item(
|
||||||
|
|
@ -265,8 +285,10 @@ pub fn context_menu<'a>(
|
||||||
if tab.mode.multiple() {
|
if tab.mode.multiple() {
|
||||||
children.push(menu_item(fl!("select-all"), Action::SelectAll).into());
|
children.push(menu_item(fl!("select-all"), Action::SelectAll).into());
|
||||||
}
|
}
|
||||||
if tab.location != Location::Recents {
|
if can_paste {
|
||||||
children.push(menu_item(fl!("paste"), Action::Paste).into());
|
children.push(menu_item(fl!("paste"), Action::Paste).into());
|
||||||
|
} else {
|
||||||
|
children.push(menu_item_disabled(fl!("paste"), Action::Paste).into());
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO: only show if cosmic-settings is found?
|
//TODO: only show if cosmic-settings is found?
|
||||||
|
|
@ -543,6 +565,7 @@ pub fn menu_bar<'a>(
|
||||||
config: &Config,
|
config: &Config,
|
||||||
modifiers: &Modifiers,
|
modifiers: &Modifiers,
|
||||||
key_binds: &HashMap<KeyBind, Action>,
|
key_binds: &HashMap<KeyBind, Action>,
|
||||||
|
clipboard_paste_available: bool,
|
||||||
) -> Element<'a, Message> {
|
) -> Element<'a, Message> {
|
||||||
let sort_options = tab_opt.map(Tab::sort_options);
|
let sort_options = tab_opt.map(Tab::sort_options);
|
||||||
let sort_item = |label, sort, dir| {
|
let sort_item = |label, sort, dir| {
|
||||||
|
|
@ -574,6 +597,10 @@ pub fn menu_bar<'a>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Allow paste when clipboard has data and we're in a location that supports it
|
||||||
|
let can_paste =
|
||||||
|
clipboard_paste_available && tab_opt.is_some_and(|tab| tab.location.supports_paste());
|
||||||
|
|
||||||
let (delete_item, delete_item_action) = if in_trash || modifiers.shift() {
|
let (delete_item, delete_item_action) = if in_trash || modifiers.shift() {
|
||||||
(fl!("delete-permanently"), Action::Delete)
|
(fl!("delete-permanently"), Action::Delete)
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -637,7 +664,7 @@ pub fn menu_bar<'a>(
|
||||||
menu_button_optional(fl!("copy"), Action::Copy, selected > 0),
|
menu_button_optional(fl!("copy"), Action::Copy, selected > 0),
|
||||||
menu_button_optional(fl!("move-to"), Action::MoveTo, selected > 0),
|
menu_button_optional(fl!("move-to"), Action::MoveTo, selected > 0),
|
||||||
menu_button_optional(fl!("copy-to"), Action::CopyTo, selected > 0),
|
menu_button_optional(fl!("copy-to"), Action::CopyTo, selected > 0),
|
||||||
menu_button_optional(fl!("paste"), Action::Paste, selected > 0),
|
menu_button_optional(fl!("paste"), Action::Paste, can_paste),
|
||||||
menu::Item::Button(fl!("select-all"), None, Action::SelectAll),
|
menu::Item::Button(fl!("select-all"), None, Action::SelectAll),
|
||||||
menu::Item::Divider,
|
menu::Item::Divider,
|
||||||
menu::Item::Button(fl!("history"), None, Action::EditHistory),
|
menu::Item::Button(fl!("history"), None, Action::EditHistory),
|
||||||
|
|
|
||||||
22
src/tab.rs
22
src/tab.rs
|
|
@ -1621,6 +1621,18 @@ impl Location {
|
||||||
_ => path,
|
_ => path,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns true if this location supports paste operations (not Trash)
|
||||||
|
pub fn supports_paste(&self) -> bool {
|
||||||
|
matches!(
|
||||||
|
self,
|
||||||
|
Self::Desktop(..)
|
||||||
|
| Self::Path(..)
|
||||||
|
| Self::Search(..)
|
||||||
|
| Self::Recents
|
||||||
|
| Self::Network(_, _, Some(_))
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct TaskWrapper(pub cosmic::Task<Message>);
|
pub struct TaskWrapper(pub cosmic::Task<Message>);
|
||||||
|
|
@ -5855,6 +5867,7 @@ impl Tab {
|
||||||
key_binds: &'a HashMap<KeyBind, Action>,
|
key_binds: &'a HashMap<KeyBind, Action>,
|
||||||
modifiers: &'a Modifiers,
|
modifiers: &'a Modifiers,
|
||||||
size: Size,
|
size: Size,
|
||||||
|
clipboard_paste_available: bool,
|
||||||
) -> Element<'a, Message> {
|
) -> Element<'a, Message> {
|
||||||
// Update cached size
|
// Update cached size
|
||||||
self.size_opt.set(Some(size));
|
self.size_opt.set(Some(size));
|
||||||
|
|
@ -5942,7 +5955,8 @@ impl Tab {
|
||||||
if let Some(point) = self.context_menu
|
if let Some(point) = self.context_menu
|
||||||
&& (!cfg!(feature = "wayland") || !crate::is_wayland())
|
&& (!cfg!(feature = "wayland") || !crate::is_wayland())
|
||||||
{
|
{
|
||||||
let context_menu = menu::context_menu(self, key_binds, modifiers);
|
let context_menu =
|
||||||
|
menu::context_menu(self, key_binds, modifiers, clipboard_paste_available);
|
||||||
popover = popover
|
popover = popover
|
||||||
.popup(context_menu)
|
.popup(context_menu)
|
||||||
.position(widget::popover::Position::Point(point));
|
.position(widget::popover::Position::Point(point));
|
||||||
|
|
@ -6149,8 +6163,12 @@ impl Tab {
|
||||||
&'a self,
|
&'a self,
|
||||||
key_binds: &'a HashMap<KeyBind, Action>,
|
key_binds: &'a HashMap<KeyBind, Action>,
|
||||||
modifiers: &'a Modifiers,
|
modifiers: &'a Modifiers,
|
||||||
|
clipboard_paste_available: bool,
|
||||||
) -> Element<'a, Message> {
|
) -> Element<'a, Message> {
|
||||||
widget::responsive(|size| self.view_responsive(key_binds, modifiers, size)).into()
|
widget::responsive(move |size| {
|
||||||
|
self.view_responsive(key_binds, modifiers, size, clipboard_paste_available)
|
||||||
|
})
|
||||||
|
.into()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn subscription(&self, preview: bool) -> Subscription<Message> {
|
pub fn subscription(&self, preview: bool) -> Subscription<Message> {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue