wayland: implement scaling
This involves many subsystems:
- config:
- allow setting the connector scale
- allow setting the cursor size
- cursors:
- load server cursors for all requested sizes and scales
- wl_surface:
- track the output the surface belongs to
- send wl_surface.enter/leave
- wl_output:
- implement wl_output.scale
- text:
- pre-render texts for all used scales
- renderer:
- properly align scale textures and rectangles
- wp_fractional_scale:
- new interface for fractional scaling
This commit is contained in:
parent
16aec8f87e
commit
e52a60b3b6
41 changed files with 1417 additions and 364 deletions
|
|
@ -149,11 +149,20 @@ pub struct WlSeatGlobal {
|
|||
output: CloneCell<Rc<OutputNode>>,
|
||||
desired_known_cursor: Cell<Option<KnownCursor>>,
|
||||
changes: NumCell<u32>,
|
||||
cursor_size: Cell<u32>,
|
||||
}
|
||||
|
||||
const CHANGE_CURSOR_MOVED: u32 = 1 << 0;
|
||||
const CHANGE_TREE: u32 = 1 << 1;
|
||||
|
||||
const DEFAULT_CURSOR_SIZE: u32 = 16;
|
||||
|
||||
impl Drop for WlSeatGlobal {
|
||||
fn drop(&mut self) {
|
||||
self.state.remove_cursor_size(self.cursor_size.get());
|
||||
}
|
||||
}
|
||||
|
||||
impl WlSeatGlobal {
|
||||
pub fn new(name: GlobalName, seat_name: &str, state: &Rc<State>) -> Rc<Self> {
|
||||
let slf = Rc::new(Self {
|
||||
|
|
@ -192,7 +201,9 @@ impl WlSeatGlobal {
|
|||
output: CloneCell::new(state.dummy_output.get().unwrap()),
|
||||
desired_known_cursor: Cell::new(None),
|
||||
changes: NumCell::new(CHANGE_CURSOR_MOVED | CHANGE_TREE),
|
||||
cursor_size: Cell::new(DEFAULT_CURSOR_SIZE),
|
||||
});
|
||||
state.add_cursor_size(DEFAULT_CURSOR_SIZE);
|
||||
let seat = slf.clone();
|
||||
let future = state.eng.spawn(async move {
|
||||
loop {
|
||||
|
|
@ -207,6 +218,15 @@ impl WlSeatGlobal {
|
|||
slf
|
||||
}
|
||||
|
||||
pub fn set_cursor_size(&self, size: u32) {
|
||||
let old = self.cursor_size.replace(size);
|
||||
if size != old {
|
||||
self.state.remove_cursor_size(old);
|
||||
self.state.add_cursor_size(size);
|
||||
self.reload_known_cursor();
|
||||
}
|
||||
}
|
||||
|
||||
pub fn add_data_device(&self, device: &Rc<WlDataDevice>) {
|
||||
let mut dd = self.data_devices.borrow_mut();
|
||||
dd.entry(device.client.id)
|
||||
|
|
@ -342,15 +362,25 @@ impl WlSeatGlobal {
|
|||
pub fn set_position(&self, x: i32, y: i32) {
|
||||
self.pos.set((Fixed::from_int(x), Fixed::from_int(y)));
|
||||
self.trigger_tree_changed();
|
||||
'set_output: {
|
||||
let output = 'set_output: {
|
||||
let outputs = self.state.outputs.lock();
|
||||
for output in outputs.values() {
|
||||
if output.node.global.pos.get().contains(x, y) {
|
||||
self.output.set(output.node.clone());
|
||||
break 'set_output;
|
||||
break 'set_output output.node.clone();
|
||||
}
|
||||
}
|
||||
self.output.set(self.state.dummy_output.get().unwrap());
|
||||
self.state.dummy_output.get().unwrap()
|
||||
};
|
||||
self.set_output(&output);
|
||||
}
|
||||
|
||||
fn set_output(&self, output: &Rc<OutputNode>) {
|
||||
self.output.set(output.clone());
|
||||
if let Some(cursor) = self.cursor.get() {
|
||||
cursor.set_output(output);
|
||||
}
|
||||
if let Some(dnd) = self.pointer_owner.dnd_icon() {
|
||||
dnd.set_output(output);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -547,6 +577,9 @@ impl WlSeatGlobal {
|
|||
icon: Option<Rc<WlSurface>>,
|
||||
serial: u32,
|
||||
) -> Result<(), WlSeatError> {
|
||||
if let Some(icon) = &icon {
|
||||
icon.set_output(&self.output.get());
|
||||
}
|
||||
self.pointer_owner
|
||||
.start_drag(self, origin, source, icon, serial)
|
||||
}
|
||||
|
|
@ -604,6 +637,12 @@ impl WlSeatGlobal {
|
|||
self.set_selection_::<PrimarySelectionIpc>(&self.primary_selection, selection)
|
||||
}
|
||||
|
||||
pub fn reload_known_cursor(&self) {
|
||||
if let Some(kc) = self.desired_known_cursor.get() {
|
||||
self.set_known_cursor(kc);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_known_cursor(&self, cursor: KnownCursor) {
|
||||
self.desired_known_cursor.set(Some(cursor));
|
||||
let cursors = match self.state.cursors.get() {
|
||||
|
|
@ -622,7 +661,7 @@ impl WlSeatGlobal {
|
|||
KnownCursor::ResizeBottomLeft => &cursors.resize_bottom_left,
|
||||
KnownCursor::ResizeBottomRight => &cursors.resize_bottom_right,
|
||||
};
|
||||
self.set_cursor2(Some(tpl.instantiate()));
|
||||
self.set_cursor2(Some(tpl.instantiate(self.cursor_size.get())));
|
||||
}
|
||||
|
||||
pub fn set_app_cursor(&self, cursor: Option<Rc<dyn Cursor>>) {
|
||||
|
|
@ -640,8 +679,7 @@ impl WlSeatGlobal {
|
|||
old.handle_unset();
|
||||
}
|
||||
if let Some(cursor) = cursor.as_ref() {
|
||||
let (x, y) = self.pos.get();
|
||||
cursor.set_position(x.round_down(), y.round_down());
|
||||
cursor.set_output(&self.output.get());
|
||||
}
|
||||
self.cursor.set(cursor);
|
||||
}
|
||||
|
|
@ -654,6 +692,10 @@ impl WlSeatGlobal {
|
|||
self.pointer_owner.remove_dnd_icon();
|
||||
}
|
||||
|
||||
pub fn get_position(&self) -> (Fixed, Fixed) {
|
||||
self.pos.get()
|
||||
}
|
||||
|
||||
pub fn get_cursor(&self) -> Option<Rc<dyn Cursor>> {
|
||||
self.cursor.get()
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue