Fix dialog placement and decorations and compact confirmation dialogs
This commit is contained in:
1 parent
24e23e2903
commit
91d2388d12
10 files changed
+83
-57
No files matched your search
@@ -282,7 +282,7 @@ fn check_grab(seat: &Seat<Ferese>, surface: &WlSurface, serial: Serial) -> Optio
|
||||
|
||||
impl XdgDecorationHandler for Ferese {
|
||||
fn new_decoration(&mut self, toplevel: ToplevelSurface) {
|
||||
let mode = self.decoration_mode_for(&toplevel);
|
||||
let mode = Mode::ServerSide;
|
||||
toplevel.with_pending_state(|state| state.decoration_mode = Some(mode));
|
||||
|
||||
// Wait for the initial surface commit so app-id and saved floating
|
||||
@@ -294,31 +294,16 @@ impl XdgDecorationHandler for Ferese {
|
||||
}
|
||||
}
|
||||
|
||||
fn request_mode(&mut self, toplevel: ToplevelSurface, _mode: Mode) {
|
||||
let mode = self.decoration_mode_for(&toplevel);
|
||||
fn request_mode(&mut self, toplevel: ToplevelSurface, mode: Mode) {
|
||||
set_decoration_mode(&toplevel, mode);
|
||||
}
|
||||
|
||||
fn unset_mode(&mut self, toplevel: ToplevelSurface) {
|
||||
let mode = self.decoration_mode_for(&toplevel);
|
||||
let mode = Mode::ServerSide;
|
||||
set_decoration_mode(&toplevel, mode);
|
||||
}
|
||||
}
|
||||
|
||||
impl Ferese {
|
||||
fn decoration_mode_for(&self, toplevel: &ToplevelSurface) -> Mode {
|
||||
self.space
|
||||
.elements()
|
||||
.find(|window| {
|
||||
window
|
||||
.toplevel()
|
||||
.is_some_and(|candidate| candidate.wl_surface() == toplevel.wl_surface())
|
||||
})
|
||||
.filter(|window| self.is_floating_window(window))
|
||||
.map_or(Mode::ServerSide, |_| Mode::ClientSide)
|
||||
}
|
||||
}
|
||||
|
||||
fn set_decoration_mode(toplevel: &ToplevelSurface, mode: Mode) {
|
||||
toplevel.with_pending_state(|state| state.decoration_mode = Some(mode));
|
||||
if initial_configure_sent(toplevel) {
|
||||
|
||||
@@ -37,7 +37,6 @@ use smithay::output::Output;
|
||||
use smithay::reexports::calloop::generic::Generic;
|
||||
use smithay::reexports::calloop::{EventLoop, Interest, LoopSignal, Mode, PostAction};
|
||||
use smithay::reexports::drm::control::crtc;
|
||||
use smithay::reexports::wayland_protocols::xdg::decoration::zv1::server::zxdg_toplevel_decoration_v1::Mode as DecorationMode;
|
||||
use smithay::reexports::wayland_protocols::xdg::shell::server::xdg_toplevel;
|
||||
use smithay::reexports::wayland_server::backend::{ClientData, ClientId, DisconnectReason, ObjectId};
|
||||
use smithay::reexports::wayland_server::protocol::wl_surface::WlSurface;
|
||||
|
||||
@@ -264,6 +264,7 @@ impl Ferese {
|
||||
})
|
||||
.and_then(|parent| self.presented_window_rect(parent))
|
||||
.and_then(|rect| intersection(rect, work));
|
||||
let dialog = crate::window_rules::is_native_dialog(app.as_deref());
|
||||
let remembered = id
|
||||
.and_then(|id| self.floating_window_memory.get(&id))
|
||||
.or_else(|| {
|
||||
@@ -273,7 +274,7 @@ impl Ferese {
|
||||
None
|
||||
}
|
||||
})
|
||||
.filter(|entry| entry.output == output)
|
||||
.filter(|entry| !dialog && entry.output == output)
|
||||
.and_then(|entry| entry.restore(&outputs));
|
||||
let (width, height) = overrides.unwrap_or_default();
|
||||
let constraints = window
|
||||
@@ -301,7 +302,9 @@ impl Ferese {
|
||||
constraints,
|
||||
);
|
||||
let dimensions = (sized.width, sized.height);
|
||||
let rect = if let Some(parent) = parent_rect {
|
||||
let rect = if dialog {
|
||||
centered(dimensions, work)
|
||||
} else if let Some(parent) = parent_rect {
|
||||
centered(dimensions, parent)
|
||||
} else if let Some(mut rect) = remembered {
|
||||
rect.width = dimensions.0;
|
||||
@@ -341,7 +344,7 @@ impl Ferese {
|
||||
return;
|
||||
};
|
||||
let (app, parent) = Self::floating_metadata(window);
|
||||
if parent.is_some() {
|
||||
if parent.is_some() || crate::window_rules::is_native_dialog(app.as_deref()) {
|
||||
return;
|
||||
}
|
||||
// A drag can finish on another output without changing workspace ownership.
|
||||
|
||||
@@ -310,15 +310,7 @@ impl Ferese {
|
||||
| state.states.unset(xdg_toplevel::State::TiledBottom)
|
||||
};
|
||||
|
||||
let decoration_mode = if is_floating && !is_fullscreen && !is_maximized {
|
||||
DecorationMode::ClientSide
|
||||
} else {
|
||||
DecorationMode::ServerSide
|
||||
};
|
||||
let decoration_changed = state.decoration_mode != Some(decoration_mode);
|
||||
state.decoration_mode = Some(decoration_mode);
|
||||
|
||||
fullscreen_changed || maximized_changed || tiled_changed || decoration_changed
|
||||
fullscreen_changed || maximized_changed || tiled_changed
|
||||
});
|
||||
|
||||
if (natural_pending || requested_size.is_some() || state_changed)
|
||||
|
||||
@@ -16,7 +16,8 @@ impl Ferese {
|
||||
|| pending.states.contains(xdg_toplevel::State::Maximized)
|
||||
});
|
||||
let rule = resolve_window_rules(&self.window_rules, app_id.as_deref(), title.as_deref(), transient);
|
||||
if transient
|
||||
if crate::window_rules::is_native_dialog(app_id.as_deref())
|
||||
|| transient
|
||||
|| special_mode
|
||||
|| rule.fullscreen == Some(true)
|
||||
|| !rule.floating.unwrap_or(rule.width.is_some() || rule.height.is_some())
|
||||
@@ -71,14 +72,17 @@ impl Ferese {
|
||||
if let Some(pointer) = self.seat.get_pointer() {
|
||||
self.focus_output_at(pointer.current_location());
|
||||
}
|
||||
let remembered_work = app_id.and_then(|app| self.floating_memory.get(app)).and_then(|entry| {
|
||||
let outputs = self.floating_outputs();
|
||||
entry.restore(&outputs)?;
|
||||
outputs
|
||||
.into_iter()
|
||||
.find(|(name, _)| *name == entry.output)
|
||||
.map(|(_, work)| work)
|
||||
});
|
||||
let remembered_work = app_id
|
||||
.filter(|app| !crate::window_rules::is_native_dialog(Some(app)))
|
||||
.and_then(|app| self.floating_memory.get(app))
|
||||
.and_then(|entry| {
|
||||
let outputs = self.floating_outputs();
|
||||
entry.restore(&outputs)?;
|
||||
outputs
|
||||
.into_iter()
|
||||
.find(|(name, _)| *name == entry.output)
|
||||
.map(|(_, work)| work)
|
||||
});
|
||||
if let Some(work) = remembered_work {
|
||||
self.focus_output_at((work.x + work.width / 2.0, work.y + work.height / 2.0).into());
|
||||
}
|
||||
|
||||
@@ -66,15 +66,7 @@ pub fn validate(configured: &[WindowRuleConfig]) -> Result<Vec<WindowRule>, Stri
|
||||
pub fn resolve(rules: &[WindowRule], app_id: Option<&str>, title: Option<&str>, transient: bool) -> WindowRuleResult {
|
||||
let app_id = app_id.map(normalize_app_id);
|
||||
let mut result = WindowRuleResult::default();
|
||||
if matches!(
|
||||
app_id.as_deref(),
|
||||
Some(
|
||||
"dev.ferese.authentication"
|
||||
| "dev.ferese.screenshare"
|
||||
| "dev.ferese.screenshot"
|
||||
| "dev.ferese.portaldialog"
|
||||
)
|
||||
) {
|
||||
if is_native_dialog(app_id.as_deref()) {
|
||||
result.floating = Some(true);
|
||||
}
|
||||
|
||||
@@ -155,6 +147,18 @@ fn positive_dimension(value: Option<f64>, index: usize, field: &'static str) ->
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn is_native_dialog(app_id: Option<&str>) -> bool {
|
||||
matches!(
|
||||
app_id.map(normalize_app_id).as_deref(),
|
||||
Some(
|
||||
"dev.ferese.authentication"
|
||||
| "dev.ferese.screenshare"
|
||||
| "dev.ferese.screenshot"
|
||||
| "dev.ferese.portaldialog"
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
fn normalize_app_id(value: &str) -> String {
|
||||
value
|
||||
.trim()
|
||||
|
||||
Reference in new issue
Block a user