1
0
Fork 0
forked from wry/wry

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:
Julian Orth 2022-05-30 17:00:25 +02:00
parent 16aec8f87e
commit e52a60b3b6
41 changed files with 1417 additions and 364 deletions

View file

@ -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()
}