Close share picker after consent without a second modal
This commit is contained in:
1 parent
7d3a88bef7
commit
96e1b6ac5a
3 files changed
+35
-93
No files matched your search
@@ -1 +0,0 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><rect x="5" y="5" width="14" height="14" rx="3" fill="currentColor"/></svg>
|
|
||||||
|
Before Width: | Height: | Size: 136 B |
+6
-27
@@ -364,14 +364,14 @@ impl Backend {
|
|||||||
}
|
}
|
||||||
let result = tokio::select! {
|
let result = tokio::select! {
|
||||||
_ = cancel.wait() => Err(StartError::Cancelled),
|
_ = cancel.wait() => Err(StartError::Cancelled),
|
||||||
result = tokio::time::timeout(Duration::from_secs(120), start_streams(if bar_controlled { "Ferese" } else { &app_id }, multiple, cursor, !bar_controlled)) => result.unwrap_or_else(|_| Err(StartError::Failed("Sharing request timed out".into()))),
|
result = tokio::time::timeout(Duration::from_secs(120), start_streams(if bar_controlled { "Ferese" } else { &app_id }, multiple, cursor)) => result.unwrap_or_else(|_| Err(StartError::Failed("Sharing request timed out".into()))),
|
||||||
};
|
};
|
||||||
let _ = connection
|
let _ = connection
|
||||||
.object_server()
|
.object_server()
|
||||||
.remove::<Request, _>(handle)
|
.remove::<Request, _>(handle)
|
||||||
.await;
|
.await;
|
||||||
match result {
|
match result {
|
||||||
Ok((children, indicator, streams)) if !cancel.stopped.load(Ordering::SeqCst) => {
|
Ok((children, streams)) if !cancel.stopped.load(Ordering::SeqCst) => {
|
||||||
if let Some(session) = self.sessions.lock().await.get_mut(session_handle.as_str()) {
|
if let Some(session) = self.sessions.lock().await.get_mut(session_handle.as_str()) {
|
||||||
session.phase = Phase::Running;
|
session.phase = Phase::Running;
|
||||||
}
|
}
|
||||||
@@ -379,7 +379,7 @@ impl Backend {
|
|||||||
let connection = connection.clone();
|
let connection = connection.clone();
|
||||||
let path = session_handle.to_string();
|
let path = session_handle.to_string();
|
||||||
tokio::spawn(async move {
|
tokio::spawn(async move {
|
||||||
supervise(children, indicator, cancel).await;
|
supervise(children, cancel).await;
|
||||||
backend.end(&connection, &path).await;
|
backend.end(&connection, &path).await;
|
||||||
});
|
});
|
||||||
let streams: Vec<(u32, Options)> = streams
|
let streams: Vec<(u32, Options)> = streams
|
||||||
@@ -488,8 +488,7 @@ async fn start_streams(
|
|||||||
app: &str,
|
app: &str,
|
||||||
multiple: bool,
|
multiple: bool,
|
||||||
cursor: bool,
|
cursor: bool,
|
||||||
show_indicator: bool,
|
) -> Result<(Vec<Child>, Vec<Ready>), StartError> {
|
||||||
) -> Result<(Vec<Child>, Option<Child>, Vec<Ready>), StartError> {
|
|
||||||
let sources = tokio::task::spawn_blocking(|| {
|
let sources = tokio::task::spawn_blocking(|| {
|
||||||
Capture::connect(&AtomicBool::new(false)).map(|capture| capture.sources())
|
Capture::connect(&AtomicBool::new(false)).map(|capture| capture.sources())
|
||||||
})
|
})
|
||||||
@@ -499,7 +498,6 @@ async fn start_streams(
|
|||||||
app: app.to_owned(),
|
app: app.to_owned(),
|
||||||
sources,
|
sources,
|
||||||
multiple,
|
multiple,
|
||||||
indicator: false,
|
|
||||||
};
|
};
|
||||||
let selection = picker(&prompt)
|
let selection = picker(&prompt)
|
||||||
.await?
|
.await?
|
||||||
@@ -544,20 +542,7 @@ async fn start_streams(
|
|||||||
streams.push(ready);
|
streams.push(ready);
|
||||||
children.push(child);
|
children.push(child);
|
||||||
}
|
}
|
||||||
let indicator = if show_indicator {
|
Ok((children, streams))
|
||||||
Some(
|
|
||||||
picker(&Prompt {
|
|
||||||
app: app.to_owned(),
|
|
||||||
sources: selected,
|
|
||||||
multiple,
|
|
||||||
indicator: true,
|
|
||||||
})
|
|
||||||
.await?,
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
};
|
|
||||||
Ok((children, indicator, streams))
|
|
||||||
}
|
}
|
||||||
fn validate_selection(
|
fn validate_selection(
|
||||||
sources: &[Source],
|
sources: &[Source],
|
||||||
@@ -582,12 +567,9 @@ fn validate_selection(
|
|||||||
}
|
}
|
||||||
Ok(selected)
|
Ok(selected)
|
||||||
}
|
}
|
||||||
async fn supervise(mut children: Vec<Child>, mut indicator: Option<Child>, cancel: Arc<Cancel>) {
|
async fn supervise(mut children: Vec<Child>, cancel: Arc<Cancel>) {
|
||||||
loop {
|
loop {
|
||||||
if cancel.stopped.load(Ordering::SeqCst)
|
if cancel.stopped.load(Ordering::SeqCst)
|
||||||
|| indicator
|
|
||||||
.as_mut()
|
|
||||||
.is_some_and(|child| !matches!(child.try_wait(), Ok(None)))
|
|
||||||
|| children
|
|| children
|
||||||
.iter_mut()
|
.iter_mut()
|
||||||
.any(|c| !matches!(c.try_wait(), Ok(None)))
|
.any(|c| !matches!(c.try_wait(), Ok(None)))
|
||||||
@@ -600,9 +582,6 @@ async fn supervise(mut children: Vec<Child>, mut indicator: Option<Child>, cance
|
|||||||
for child in &mut children {
|
for child in &mut children {
|
||||||
let _ = child.kill().await;
|
let _ = child.kill().await;
|
||||||
}
|
}
|
||||||
if let Some(indicator) = &mut indicator {
|
|
||||||
let _ = indicator.kill().await;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
pub async fn run() -> Result<(), Box<dyn std::error::Error>> {
|
pub async fn run() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
let backend = Backend::default();
|
let backend = Backend::default();
|
||||||
|
|||||||
+29
-65
@@ -13,7 +13,6 @@ pub struct Prompt {
|
|||||||
pub app: String,
|
pub app: String,
|
||||||
pub sources: Vec<Source>,
|
pub sources: Vec<Source>,
|
||||||
pub multiple: bool,
|
pub multiple: bool,
|
||||||
pub indicator: bool,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
@@ -86,15 +85,10 @@ impl cosmic::Application for Picker {
|
|||||||
background,
|
background,
|
||||||
foreground,
|
foreground,
|
||||||
};
|
};
|
||||||
let title = if app.prompt.indicator {
|
|
||||||
"Ferese — screen sharing"
|
|
||||||
} else {
|
|
||||||
"Ferese — share your screen"
|
|
||||||
};
|
|
||||||
let task = app
|
let task = app
|
||||||
.core
|
.core
|
||||||
.main_window_id()
|
.main_window_id()
|
||||||
.map(|id| app.set_window_title(title.into(), id))
|
.map(|id| app.set_window_title("Ferese — share your screen".into(), id))
|
||||||
.unwrap_or_else(Task::none);
|
.unwrap_or_else(Task::none);
|
||||||
|
|
||||||
(app, task)
|
(app, task)
|
||||||
@@ -148,18 +142,8 @@ impl cosmic::Application for Picker {
|
|||||||
row![
|
row![
|
||||||
glyph(include_bytes!("../assets/display.svg"), 24),
|
glyph(include_bytes!("../assets/display.svg"), 24),
|
||||||
column![
|
column![
|
||||||
text(if self.prompt.indicator {
|
text("Choose a display").size(18),
|
||||||
"Screen sharing"
|
text(format!("Share with {app}")).size(12),
|
||||||
} else {
|
|
||||||
"Choose a display"
|
|
||||||
})
|
|
||||||
.size(18),
|
|
||||||
text(if self.prompt.indicator {
|
|
||||||
format!("Shared with {app}")
|
|
||||||
} else {
|
|
||||||
format!("Share with {app}")
|
|
||||||
})
|
|
||||||
.size(12),
|
|
||||||
]
|
]
|
||||||
.spacing(2)
|
.spacing(2)
|
||||||
.width(Length::Fill),
|
.width(Length::Fill),
|
||||||
@@ -181,24 +165,20 @@ impl cosmic::Application for Picker {
|
|||||||
]
|
]
|
||||||
.spacing(12)
|
.spacing(12)
|
||||||
.align_y(Alignment::Center);
|
.align_y(Alignment::Center);
|
||||||
if selected || self.prompt.indicator {
|
if selected {
|
||||||
entry = entry.push(glyph(include_bytes!("../assets/check.svg"), 20));
|
entry = entry.push(glyph(include_bytes!("../assets/check.svg"), 20));
|
||||||
}
|
}
|
||||||
if self.prompt.indicator {
|
sources = sources.push(
|
||||||
sources = sources.push(container(entry).padding(8).width(Length::Fill));
|
button::custom(entry)
|
||||||
} else {
|
.class(if selected {
|
||||||
sources = sources.push(
|
ferese_theme::accent_button()
|
||||||
button::custom(entry)
|
} else {
|
||||||
.class(if selected {
|
cosmic::theme::Button::Standard
|
||||||
ferese_theme::accent_button()
|
})
|
||||||
} else {
|
.padding(8)
|
||||||
cosmic::theme::Button::Standard
|
.width(Length::Fill)
|
||||||
})
|
.on_press(Message::Select(index)),
|
||||||
.padding(8)
|
);
|
||||||
.width(Length::Fill)
|
|
||||||
.on_press(Message::Select(index)),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
content = content.push(scrollable(sources).height(Length::Fixed(
|
content = content.push(scrollable(sources).height(Length::Fixed(
|
||||||
(self.prompt.sources.len().min(4) * 56) as f32,
|
(self.prompt.sources.len().min(4) * 56) as f32,
|
||||||
@@ -208,37 +188,21 @@ impl cosmic::Application for Picker {
|
|||||||
.size(12)
|
.size(12)
|
||||||
.width(Length::Fill),
|
.width(Length::Fill),
|
||||||
);
|
);
|
||||||
if self.prompt.indicator {
|
let mut share = button::custom(
|
||||||
content = content.push(
|
row![
|
||||||
button::custom(
|
text("Share"),
|
||||||
row![
|
glyph(include_bytes!("../assets/arrow.svg"), 16)
|
||||||
glyph(include_bytes!("../assets/stop.svg"), 16),
|
]
|
||||||
text("Stop sharing")
|
.spacing(8)
|
||||||
]
|
.align_y(Alignment::Center),
|
||||||
.spacing(8)
|
)
|
||||||
.align_y(Alignment::Center),
|
.class(ferese_theme::accent_button())
|
||||||
)
|
.padding([6, 16]);
|
||||||
.class(cosmic::theme::Button::Destructive)
|
if !self.selected.is_empty() {
|
||||||
.padding([6, 16])
|
share = share.on_press(Message::Share);
|
||||||
.on_press(Message::Cancel),
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
let mut share = button::custom(
|
|
||||||
row![
|
|
||||||
text("Share"),
|
|
||||||
glyph(include_bytes!("../assets/arrow.svg"), 16)
|
|
||||||
]
|
|
||||||
.spacing(8)
|
|
||||||
.align_y(Alignment::Center),
|
|
||||||
)
|
|
||||||
.class(ferese_theme::accent_button())
|
|
||||||
.padding([6, 16]);
|
|
||||||
if !self.selected.is_empty() {
|
|
||||||
share = share.on_press(Message::Share);
|
|
||||||
}
|
|
||||||
content = content
|
|
||||||
.push(row![button::text("Cancel").on_press(Message::Cancel), share].spacing(8));
|
|
||||||
}
|
}
|
||||||
|
content =
|
||||||
|
content.push(row![button::text("Cancel").on_press(Message::Cancel), share].spacing(8));
|
||||||
container(content).padding(14).width(Length::Fill).into()
|
container(content).padding(14).width(Length::Fill).into()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in new issue
Block a user