output: Take transform into account
Without handling transform, the surface was created with the wrong size on rotated displays, causing flicker before the .configure event arrived. With, it will attempt to set the right size from the start.
This commit is contained in:
133
src/outputs.rs
133
src/outputs.rs
@ -59,6 +59,36 @@ pub mod c {
|
||||
}
|
||||
}
|
||||
|
||||
/// Map to `wl_output.transform` values
|
||||
#[derive(Clone)]
|
||||
pub enum Transform {
|
||||
Normal = 0,
|
||||
Rotated90 = 1,
|
||||
Rotated180 = 2,
|
||||
Rotated270 = 3,
|
||||
Flipped = 4,
|
||||
FlippedRotated90 = 5,
|
||||
FlippedRotated180 = 6,
|
||||
FlippedRotated270 = 7,
|
||||
}
|
||||
|
||||
impl Transform {
|
||||
fn from_u32(v: u32) -> Option<Transform> {
|
||||
use self::Transform::*;
|
||||
match v {
|
||||
0 => Some(Normal),
|
||||
1 => Some(Rotated90),
|
||||
2 => Some(Rotated180),
|
||||
3 => Some(Rotated270),
|
||||
4 => Some(Flipped),
|
||||
5 => Some(FlippedRotated90),
|
||||
6 => Some(FlippedRotated180),
|
||||
7 => Some(FlippedRotated270),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
// Rustc wrongly assumes
|
||||
// that COutputs allows C direct access to the underlying RefCell
|
||||
@ -75,16 +105,32 @@ pub mod c {
|
||||
// Defined in Rust
|
||||
|
||||
extern fn outputs_handle_geometry(
|
||||
_outputs: COutputs,
|
||||
_wl_output: WlOutput,
|
||||
outputs: COutputs,
|
||||
wl_output: WlOutput,
|
||||
_x: i32, _y: i32,
|
||||
_phys_width: i32, _phys_height: i32,
|
||||
_subpixel: i32,
|
||||
_make: *const c_char, _model: *const c_char,
|
||||
_transform: i32,
|
||||
transform: i32,
|
||||
) {
|
||||
//println!("geometry handled {},{}", x, y);
|
||||
// Totally unused
|
||||
let transform = Transform::from_u32(transform as u32).unwrap_or_else(
|
||||
|| {
|
||||
eprintln!(
|
||||
"Warning: received invalid wl_output.transform value"
|
||||
);
|
||||
Transform::Normal
|
||||
}
|
||||
);
|
||||
|
||||
let outputs = outputs.clone_ref();
|
||||
let mut collection = outputs.borrow_mut();
|
||||
let output_state: Option<&mut OutputState>
|
||||
= find_output_mut(&mut collection, wl_output)
|
||||
.map(|o| &mut o.pending);
|
||||
match output_state {
|
||||
Some(state) => { state.transform = Some(transform) },
|
||||
None => eprintln!("Wayland error: Got mode on unknown output"),
|
||||
};
|
||||
}
|
||||
|
||||
extern fn outputs_handle_mode(
|
||||
@ -100,14 +146,12 @@ pub mod c {
|
||||
Mode::NONE
|
||||
});
|
||||
let outputs = outputs.clone_ref();
|
||||
let mut outputs = outputs.borrow_mut();
|
||||
let mut output_state: Option<&mut OutputState> = outputs.outputs
|
||||
.iter_mut()
|
||||
.find_map(|o|
|
||||
if o.output == wl_output { Some(&mut o.pending) } else { None }
|
||||
);
|
||||
let mut collection = outputs.borrow_mut();
|
||||
let output_state: Option<&mut OutputState>
|
||||
= find_output_mut(&mut collection, wl_output)
|
||||
.map(|o| &mut o.pending);
|
||||
match output_state {
|
||||
Some(ref mut state) => {
|
||||
Some(state) => {
|
||||
if flags.contains(Mode::CURRENT) {
|
||||
state.current_mode = Some(super::Mode { width, height});
|
||||
}
|
||||
@ -121,12 +165,10 @@ pub mod c {
|
||||
wl_output: WlOutput,
|
||||
) {
|
||||
let outputs = outputs.clone_ref();
|
||||
let mut outputs = outputs.borrow_mut();
|
||||
let mut output = outputs.outputs
|
||||
.iter_mut()
|
||||
.find(|o| o.output == wl_output);
|
||||
let mut collection = outputs.borrow_mut();
|
||||
let output = find_output_mut(&mut collection, wl_output);
|
||||
match output {
|
||||
Some(ref mut output) => { output.current = output.pending.clone(); }
|
||||
Some(output) => { output.current = output.pending.clone(); }
|
||||
None => eprintln!("Wayland error: Got done on unknown output"),
|
||||
};
|
||||
}
|
||||
@ -137,12 +179,10 @@ pub mod c {
|
||||
factor: i32,
|
||||
) {
|
||||
let outputs = outputs.clone_ref();
|
||||
let mut outputs = outputs.borrow_mut();
|
||||
let output_state = outputs.outputs
|
||||
.iter_mut()
|
||||
.find_map(|o|
|
||||
if o.output == wl_output { Some(&mut o.pending) } else { None }
|
||||
);
|
||||
let mut collection = outputs.borrow_mut();
|
||||
let output_state: Option<&mut OutputState>
|
||||
= find_output_mut(&mut collection, wl_output)
|
||||
.map(|o| &mut o.pending);
|
||||
match output_state {
|
||||
Some(state) => { state.scale = factor; }
|
||||
None => eprintln!("Wayland error: Got done on unknown output"),
|
||||
@ -201,24 +241,51 @@ pub mod c {
|
||||
let collection = raw_collection.clone_ref();
|
||||
let collection = collection.borrow();
|
||||
|
||||
let output_state = collection.outputs
|
||||
.iter()
|
||||
.find_map(|o|
|
||||
if o.output == wl_output { Some(&o.current) } else { None }
|
||||
);
|
||||
|
||||
let output_state = find_output(&collection, wl_output)
|
||||
.map(|o| &o.current);
|
||||
match output_state {
|
||||
Some(OutputState {
|
||||
current_mode: Some(super::Mode { width, height: _ } ),
|
||||
current_mode: Some(super::Mode { width, height } ),
|
||||
transform: Some(transform),
|
||||
scale,
|
||||
}) => width / scale,
|
||||
}) => {
|
||||
match transform {
|
||||
Transform::Normal
|
||||
| Transform::Rotated180
|
||||
| Transform::Flipped
|
||||
| Transform::FlippedRotated180 => width / scale,
|
||||
_ => height / scale,
|
||||
}
|
||||
},
|
||||
_ => {
|
||||
eprintln!("No width registered on output");
|
||||
eprintln!("Not enough info registered on output");
|
||||
0
|
||||
},
|
||||
}
|
||||
}
|
||||
// TODO: handle unregistration
|
||||
|
||||
fn find_output(
|
||||
collection: &Outputs,
|
||||
wl_output: WlOutput,
|
||||
) -> Option<&Output> {
|
||||
collection.outputs
|
||||
.iter()
|
||||
.find_map(|o|
|
||||
if o.output == wl_output { Some(o) } else { None }
|
||||
)
|
||||
}
|
||||
|
||||
fn find_output_mut(
|
||||
collection: &mut Outputs,
|
||||
wl_output: WlOutput,
|
||||
) -> Option<&mut Output> {
|
||||
collection.outputs
|
||||
.iter_mut()
|
||||
.find_map(|o|
|
||||
if o.output == wl_output { Some(o) } else { None }
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
@ -230,6 +297,7 @@ struct Mode {
|
||||
#[derive(Clone)]
|
||||
pub struct OutputState {
|
||||
current_mode: Option<Mode>,
|
||||
transform: Option<c::Transform>,
|
||||
scale: i32,
|
||||
}
|
||||
|
||||
@ -237,6 +305,7 @@ impl OutputState {
|
||||
fn uninitialized() -> OutputState {
|
||||
OutputState {
|
||||
current_mode: None,
|
||||
transform: None,
|
||||
scale: 1,
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user