2024-02-06 09:01:26 +04:00
|
|
|
use std::cell::RefCell;
|
|
|
|
|
use std::cmp::{max, min};
|
|
|
|
|
use std::rc::Rc;
|
|
|
|
|
|
2024-05-10 16:58:53 +04:00
|
|
|
use niri::layout::{
|
|
|
|
|
InteractiveResizeData, LayoutElement, LayoutElementRenderElement, LayoutElementRenderSnapshot,
|
|
|
|
|
};
|
2024-02-06 11:24:50 +04:00
|
|
|
use niri::render_helpers::renderer::NiriRenderer;
|
2024-05-01 19:02:22 +04:00
|
|
|
use niri::render_helpers::{RenderTarget, SplitElements};
|
2024-03-19 18:22:25 +04:00
|
|
|
use niri::window::ResolvedWindowRules;
|
2024-02-06 09:01:26 +04:00
|
|
|
use smithay::backend::renderer::element::solid::{SolidColorBuffer, SolidColorRenderElement};
|
2024-02-07 11:32:02 +04:00
|
|
|
use smithay::backend::renderer::element::{Id, Kind};
|
2024-02-06 09:01:26 +04:00
|
|
|
use smithay::output::Output;
|
|
|
|
|
use smithay::reexports::wayland_server::protocol::wl_surface::WlSurface;
|
2024-05-10 16:58:53 +04:00
|
|
|
use smithay::utils::{Logical, Point, Scale, Serial, Size, Transform};
|
2024-02-06 09:01:26 +04:00
|
|
|
|
|
|
|
|
#[derive(Debug)]
|
|
|
|
|
struct TestWindowInner {
|
|
|
|
|
size: Size<i32, Logical>,
|
|
|
|
|
requested_size: Option<Size<i32, Logical>>,
|
|
|
|
|
min_size: Size<i32, Logical>,
|
|
|
|
|
max_size: Size<i32, Logical>,
|
|
|
|
|
buffer: SolidColorBuffer,
|
|
|
|
|
pending_fullscreen: bool,
|
|
|
|
|
csd_shadow_width: i32,
|
|
|
|
|
csd_shadow_buffer: SolidColorBuffer,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Debug, Clone)]
|
2024-03-19 13:42:04 +04:00
|
|
|
pub struct TestWindow {
|
|
|
|
|
id: usize,
|
|
|
|
|
inner: Rc<RefCell<TestWindowInner>>,
|
|
|
|
|
}
|
2024-02-06 09:01:26 +04:00
|
|
|
|
|
|
|
|
impl TestWindow {
|
|
|
|
|
pub fn freeform(id: usize) -> Self {
|
|
|
|
|
let size = Size::from((100, 200));
|
|
|
|
|
let min_size = Size::from((0, 0));
|
|
|
|
|
let max_size = Size::from((0, 0));
|
|
|
|
|
let buffer = SolidColorBuffer::new(size, [0.15, 0.64, 0.41, 1.]);
|
|
|
|
|
|
2024-03-19 13:42:04 +04:00
|
|
|
Self {
|
2024-02-06 09:01:26 +04:00
|
|
|
id,
|
2024-03-19 13:42:04 +04:00
|
|
|
inner: Rc::new(RefCell::new(TestWindowInner {
|
|
|
|
|
size,
|
|
|
|
|
requested_size: None,
|
|
|
|
|
min_size,
|
|
|
|
|
max_size,
|
|
|
|
|
buffer,
|
|
|
|
|
pending_fullscreen: false,
|
|
|
|
|
csd_shadow_width: 0,
|
|
|
|
|
csd_shadow_buffer: SolidColorBuffer::new((0, 0), [0., 0., 0., 0.3]),
|
|
|
|
|
})),
|
|
|
|
|
}
|
2024-02-06 09:01:26 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn fixed_size(id: usize) -> Self {
|
|
|
|
|
let rv = Self::freeform(id);
|
|
|
|
|
rv.set_min_size((200, 400).into());
|
|
|
|
|
rv.set_max_size((200, 400).into());
|
|
|
|
|
rv.set_color([0.88, 0.11, 0.14, 1.]);
|
|
|
|
|
rv.communicate();
|
|
|
|
|
rv
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn set_min_size(&self, size: Size<i32, Logical>) {
|
2024-03-19 13:42:04 +04:00
|
|
|
self.inner.borrow_mut().min_size = size;
|
2024-02-06 09:01:26 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn set_max_size(&self, size: Size<i32, Logical>) {
|
2024-03-19 13:42:04 +04:00
|
|
|
self.inner.borrow_mut().max_size = size;
|
2024-02-06 09:01:26 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn set_color(&self, color: [f32; 4]) {
|
2024-03-19 13:42:04 +04:00
|
|
|
self.inner.borrow_mut().buffer.set_color(color);
|
2024-02-06 09:01:26 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn set_csd_shadow_width(&self, width: i32) {
|
2024-03-19 13:42:04 +04:00
|
|
|
self.inner.borrow_mut().csd_shadow_width = width;
|
2024-02-06 09:01:26 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn communicate(&self) -> bool {
|
|
|
|
|
let mut rv = false;
|
2024-03-19 13:42:04 +04:00
|
|
|
let mut inner = self.inner.borrow_mut();
|
2024-02-06 09:01:26 +04:00
|
|
|
|
|
|
|
|
let mut new_size = inner.size;
|
|
|
|
|
|
|
|
|
|
if let Some(size) = inner.requested_size.take() {
|
|
|
|
|
assert!(size.w >= 0);
|
|
|
|
|
assert!(size.h >= 0);
|
|
|
|
|
|
|
|
|
|
if size.w != 0 {
|
|
|
|
|
new_size.w = size.w;
|
|
|
|
|
}
|
|
|
|
|
if size.h != 0 {
|
|
|
|
|
new_size.h = size.h;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if inner.max_size.w > 0 {
|
|
|
|
|
new_size.w = min(new_size.w, inner.max_size.w);
|
|
|
|
|
}
|
|
|
|
|
if inner.max_size.h > 0 {
|
|
|
|
|
new_size.h = min(new_size.h, inner.max_size.h);
|
|
|
|
|
}
|
|
|
|
|
if inner.min_size.w > 0 {
|
|
|
|
|
new_size.w = max(new_size.w, inner.min_size.w);
|
|
|
|
|
}
|
|
|
|
|
if inner.min_size.h > 0 {
|
|
|
|
|
new_size.h = max(new_size.h, inner.min_size.h);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if inner.size != new_size {
|
|
|
|
|
inner.size = new_size;
|
|
|
|
|
inner.buffer.resize(new_size);
|
|
|
|
|
rv = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let mut csd_shadow_size = new_size;
|
|
|
|
|
csd_shadow_size.w += inner.csd_shadow_width * 2;
|
|
|
|
|
csd_shadow_size.h += inner.csd_shadow_width * 2;
|
|
|
|
|
inner.csd_shadow_buffer.resize(csd_shadow_size);
|
|
|
|
|
|
|
|
|
|
rv
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-19 13:42:04 +04:00
|
|
|
impl LayoutElement for TestWindow {
|
|
|
|
|
type Id = usize;
|
|
|
|
|
|
|
|
|
|
fn id(&self) -> &Self::Id {
|
|
|
|
|
&self.id
|
2024-02-06 09:01:26 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn size(&self) -> Size<i32, Logical> {
|
2024-03-19 13:42:04 +04:00
|
|
|
self.inner.borrow().size
|
2024-02-06 09:01:26 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn buf_loc(&self) -> Point<i32, Logical> {
|
|
|
|
|
(0, 0).into()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn is_in_input_region(&self, _point: Point<f64, Logical>) -> bool {
|
|
|
|
|
false
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn render<R: NiriRenderer>(
|
|
|
|
|
&self,
|
|
|
|
|
_renderer: &mut R,
|
|
|
|
|
location: Point<i32, Logical>,
|
|
|
|
|
scale: Scale<f64>,
|
2024-03-24 08:30:26 +04:00
|
|
|
alpha: f32,
|
2024-03-24 09:03:59 +04:00
|
|
|
_target: RenderTarget,
|
2024-05-01 19:02:22 +04:00
|
|
|
) -> SplitElements<LayoutElementRenderElement<R>> {
|
2024-03-19 13:42:04 +04:00
|
|
|
let inner = self.inner.borrow();
|
2024-02-06 09:01:26 +04:00
|
|
|
|
2024-05-01 19:02:22 +04:00
|
|
|
SplitElements {
|
|
|
|
|
normal: vec![
|
|
|
|
|
SolidColorRenderElement::from_buffer(
|
|
|
|
|
&inner.buffer,
|
|
|
|
|
location.to_physical_precise_round(scale),
|
|
|
|
|
scale,
|
|
|
|
|
alpha,
|
|
|
|
|
Kind::Unspecified,
|
|
|
|
|
)
|
|
|
|
|
.into(),
|
|
|
|
|
SolidColorRenderElement::from_buffer(
|
|
|
|
|
&inner.csd_shadow_buffer,
|
|
|
|
|
(location - Point::from((inner.csd_shadow_width, inner.csd_shadow_width)))
|
|
|
|
|
.to_physical_precise_round(scale),
|
|
|
|
|
scale,
|
|
|
|
|
alpha,
|
|
|
|
|
Kind::Unspecified,
|
|
|
|
|
)
|
|
|
|
|
.into(),
|
|
|
|
|
],
|
|
|
|
|
popups: vec![],
|
|
|
|
|
}
|
2024-02-06 09:01:26 +04:00
|
|
|
}
|
|
|
|
|
|
2024-04-13 11:07:23 +04:00
|
|
|
fn request_size(&mut self, size: Size<i32, Logical>, _animate: bool) {
|
2024-03-19 13:42:04 +04:00
|
|
|
self.inner.borrow_mut().requested_size = Some(size);
|
|
|
|
|
self.inner.borrow_mut().pending_fullscreen = false;
|
2024-02-06 09:01:26 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn request_fullscreen(&self, _size: Size<i32, Logical>) {
|
2024-03-19 13:42:04 +04:00
|
|
|
self.inner.borrow_mut().pending_fullscreen = true;
|
2024-02-06 09:01:26 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn min_size(&self) -> Size<i32, Logical> {
|
2024-03-19 13:42:04 +04:00
|
|
|
self.inner.borrow().min_size
|
2024-02-06 09:01:26 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn max_size(&self) -> Size<i32, Logical> {
|
2024-03-19 13:42:04 +04:00
|
|
|
self.inner.borrow().max_size
|
2024-02-06 09:01:26 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn is_wl_surface(&self, _wl_surface: &WlSurface) -> bool {
|
|
|
|
|
false
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn set_preferred_scale_transform(&self, _scale: i32, _transform: Transform) {}
|
|
|
|
|
|
|
|
|
|
fn has_ssd(&self) -> bool {
|
|
|
|
|
false
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn output_enter(&self, _output: &Output) {}
|
|
|
|
|
|
|
|
|
|
fn output_leave(&self, _output: &Output) {}
|
|
|
|
|
|
2024-02-07 11:32:02 +04:00
|
|
|
fn set_offscreen_element_id(&self, _id: Option<Id>) {}
|
|
|
|
|
|
2024-03-23 14:38:07 +04:00
|
|
|
fn set_activated(&mut self, _active: bool) {}
|
2024-03-19 13:52:08 +04:00
|
|
|
|
2024-04-22 22:51:52 +02:00
|
|
|
fn set_active_in_column(&mut self, _active: bool) {}
|
|
|
|
|
|
2024-03-19 13:52:08 +04:00
|
|
|
fn set_bounds(&self, _bounds: Size<i32, Logical>) {}
|
|
|
|
|
|
2024-04-13 11:07:23 +04:00
|
|
|
fn send_pending_configure(&mut self) {}
|
2024-03-19 13:52:08 +04:00
|
|
|
|
2024-02-06 09:01:26 +04:00
|
|
|
fn is_fullscreen(&self) -> bool {
|
|
|
|
|
false
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn is_pending_fullscreen(&self) -> bool {
|
2024-03-19 13:42:04 +04:00
|
|
|
self.inner.borrow().pending_fullscreen
|
2024-02-06 09:01:26 +04:00
|
|
|
}
|
2024-03-19 13:52:08 +04:00
|
|
|
|
|
|
|
|
fn refresh(&self) {}
|
2024-03-19 18:22:25 +04:00
|
|
|
|
|
|
|
|
fn rules(&self) -> &ResolvedWindowRules {
|
|
|
|
|
static EMPTY: ResolvedWindowRules = ResolvedWindowRules::empty();
|
|
|
|
|
&EMPTY
|
|
|
|
|
}
|
2024-04-13 11:07:23 +04:00
|
|
|
|
2024-04-13 14:16:07 +04:00
|
|
|
fn animation_snapshot(&self) -> Option<&LayoutElementRenderSnapshot> {
|
2024-04-13 11:07:23 +04:00
|
|
|
None
|
|
|
|
|
}
|
|
|
|
|
|
2024-04-13 14:16:07 +04:00
|
|
|
fn take_animation_snapshot(&mut self) -> Option<LayoutElementRenderSnapshot> {
|
2024-04-13 11:07:23 +04:00
|
|
|
None
|
|
|
|
|
}
|
2024-05-10 16:58:53 +04:00
|
|
|
|
|
|
|
|
fn set_interactive_resize(&mut self, _data: Option<InteractiveResizeData>) {}
|
|
|
|
|
|
|
|
|
|
fn cancel_interactive_resize(&mut self) {}
|
|
|
|
|
|
2024-05-11 08:26:49 +04:00
|
|
|
fn update_interactive_resize(&mut self, _serial: Serial) {}
|
|
|
|
|
|
|
|
|
|
fn interactive_resize_data(&self) -> Option<InteractiveResizeData> {
|
2024-05-10 16:58:53 +04:00
|
|
|
None
|
|
|
|
|
}
|
2024-02-06 09:01:26 +04:00
|
|
|
}
|