mirror of
https://codeberg.org/waydeer/layer-shika.git
synced 2025-12-02 20:15:54 +00:00
refactor: output handling and output registry
This commit is contained in:
parent
49432eecd2
commit
fc4604c758
11 changed files with 263 additions and 131 deletions
|
|
@ -169,16 +169,16 @@ impl Dispatch<WlPointer, ()> for AppState {
|
||||||
if let Some(window) = state.get_output_by_surface_mut(&surface_id) {
|
if let Some(window) = state.get_output_by_surface_mut(&surface_id) {
|
||||||
window.handle_pointer_enter(serial, &surface, surface_x, surface_y);
|
window.handle_pointer_enter(serial, &surface, surface_x, surface_y);
|
||||||
|
|
||||||
if let Some(key) = state.get_key_by_surface(&surface_id) {
|
if let Some(handle) = state.get_handle_by_surface(&surface_id) {
|
||||||
state.set_active_output(Some(key));
|
state.set_active_output_handle(Some(handle));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let key = state.get_key_by_popup(&surface_id);
|
let handle = state.get_handle_by_popup(&surface_id);
|
||||||
if let Some(window) = state.find_output_by_popup_mut(&surface_id) {
|
if let Some(window) = state.find_output_by_popup_mut(&surface_id) {
|
||||||
window.handle_pointer_enter(serial, &surface, surface_x, surface_y);
|
window.handle_pointer_enter(serial, &surface, surface_x, surface_y);
|
||||||
|
|
||||||
if let Some(key) = key {
|
if let Some(handle) = handle {
|
||||||
state.set_active_output(Some(key));
|
state.set_active_output_handle(Some(handle));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -189,20 +189,20 @@ impl Dispatch<WlPointer, ()> for AppState {
|
||||||
surface_y,
|
surface_y,
|
||||||
..
|
..
|
||||||
} => {
|
} => {
|
||||||
if let Some(output_key) = state.active_output() {
|
if let Some(output_handle) = state.active_output_handle() {
|
||||||
if let Some(window) = state.get_output_by_key_mut(&output_key) {
|
if let Some(window) = state.get_output_by_handle_mut(output_handle) {
|
||||||
window.handle_pointer_motion(surface_x, surface_y);
|
window.handle_pointer_motion(surface_x, surface_y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
wl_pointer::Event::Leave { .. } => {
|
wl_pointer::Event::Leave { .. } => {
|
||||||
if let Some(output_key) = state.active_output() {
|
if let Some(output_handle) = state.active_output_handle() {
|
||||||
if let Some(window) = state.get_output_by_key_mut(&output_key) {
|
if let Some(window) = state.get_output_by_handle_mut(output_handle) {
|
||||||
window.handle_pointer_leave();
|
window.handle_pointer_leave();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
state.set_active_output(None);
|
state.set_active_output_handle(None);
|
||||||
}
|
}
|
||||||
|
|
||||||
wl_pointer::Event::Button {
|
wl_pointer::Event::Button {
|
||||||
|
|
@ -210,8 +210,8 @@ impl Dispatch<WlPointer, ()> for AppState {
|
||||||
state: button_state,
|
state: button_state,
|
||||||
..
|
..
|
||||||
} => {
|
} => {
|
||||||
if let Some(output_key) = state.active_output() {
|
if let Some(output_handle) = state.active_output_handle() {
|
||||||
if let Some(window) = state.get_output_by_key_mut(&output_key) {
|
if let Some(window) = state.get_output_by_handle_mut(output_handle) {
|
||||||
window.handle_pointer_button(serial, button_state);
|
window.handle_pointer_button(serial, button_state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,42 +1,36 @@
|
||||||
use layer_shika_domain::value_objects::output_handle::OutputHandle;
|
use layer_shika_domain::value_objects::output_handle::OutputHandle;
|
||||||
use std::collections::hash_map::DefaultHasher;
|
use std::collections::HashMap;
|
||||||
use std::hash::{Hash, Hasher};
|
|
||||||
use wayland_client::backend::ObjectId;
|
use wayland_client::backend::ObjectId;
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
pub struct OutputMapping {
|
||||||
pub struct OutputKey {
|
object_to_handle: HashMap<ObjectId, OutputHandle>,
|
||||||
handle: OutputHandle,
|
|
||||||
_object_id_hash: u64,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl OutputKey {
|
impl OutputMapping {
|
||||||
pub fn new(object_id: &ObjectId) -> Self {
|
pub fn new() -> Self {
|
||||||
let mut hasher = DefaultHasher::new();
|
|
||||||
object_id.hash(&mut hasher);
|
|
||||||
let object_id_hash = hasher.finish();
|
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
handle: OutputHandle::new(),
|
object_to_handle: HashMap::new(),
|
||||||
_object_id_hash: object_id_hash,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const fn handle(&self) -> OutputHandle {
|
pub fn insert(&mut self, object_id: ObjectId) -> OutputHandle {
|
||||||
self.handle
|
let handle = OutputHandle::new();
|
||||||
|
self.object_to_handle.insert(object_id, handle);
|
||||||
|
handle
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get(&self, object_id: &ObjectId) -> Option<OutputHandle> {
|
||||||
|
self.object_to_handle.get(object_id).copied()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
|
pub fn remove(&mut self, object_id: &ObjectId) -> Option<OutputHandle> {
|
||||||
|
self.object_to_handle.remove(object_id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<ObjectId> for OutputKey {
|
impl Default for OutputMapping {
|
||||||
fn from(id: ObjectId) -> Self {
|
fn default() -> Self {
|
||||||
Self::new(&id)
|
Self::new()
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<OutputHandle> for OutputKey {
|
|
||||||
fn from(handle: OutputHandle) -> Self {
|
|
||||||
Self {
|
|
||||||
handle,
|
|
||||||
_object_id_hash: 0,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,8 @@
|
||||||
use super::event_context::SharedPointerSerial;
|
use super::event_context::SharedPointerSerial;
|
||||||
use super::surface_state::WindowState;
|
use super::surface_state::WindowState;
|
||||||
use crate::wayland::managed_proxies::ManagedWlPointer;
|
use crate::wayland::managed_proxies::ManagedWlPointer;
|
||||||
use crate::wayland::outputs::OutputKey;
|
use crate::wayland::outputs::OutputMapping;
|
||||||
|
use layer_shika_domain::entities::output_registry::OutputRegistry;
|
||||||
use layer_shika_domain::value_objects::output_handle::OutputHandle;
|
use layer_shika_domain::value_objects::output_handle::OutputHandle;
|
||||||
use layer_shika_domain::value_objects::output_info::OutputInfo;
|
use layer_shika_domain::value_objects::output_info::OutputInfo;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
@ -12,27 +13,23 @@ use wayland_client::backend::ObjectId;
|
||||||
pub type PerOutputWindow = WindowState;
|
pub type PerOutputWindow = WindowState;
|
||||||
|
|
||||||
pub struct AppState {
|
pub struct AppState {
|
||||||
outputs: HashMap<OutputHandle, PerOutputWindow>,
|
output_registry: OutputRegistry,
|
||||||
output_info: HashMap<OutputHandle, OutputInfo>,
|
output_mapping: OutputMapping,
|
||||||
|
windows: HashMap<OutputHandle, PerOutputWindow>,
|
||||||
surface_to_output: HashMap<ObjectId, OutputHandle>,
|
surface_to_output: HashMap<ObjectId, OutputHandle>,
|
||||||
output_to_handle: HashMap<ObjectId, OutputHandle>,
|
|
||||||
_pointer: ManagedWlPointer,
|
_pointer: ManagedWlPointer,
|
||||||
shared_pointer_serial: Rc<SharedPointerSerial>,
|
shared_pointer_serial: Rc<SharedPointerSerial>,
|
||||||
active_output: Option<OutputHandle>,
|
|
||||||
primary_output: Option<OutputHandle>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AppState {
|
impl AppState {
|
||||||
pub fn new(pointer: ManagedWlPointer, shared_serial: Rc<SharedPointerSerial>) -> Self {
|
pub fn new(pointer: ManagedWlPointer, shared_serial: Rc<SharedPointerSerial>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
outputs: HashMap::new(),
|
output_registry: OutputRegistry::new(),
|
||||||
output_info: HashMap::new(),
|
output_mapping: OutputMapping::new(),
|
||||||
|
windows: HashMap::new(),
|
||||||
surface_to_output: HashMap::new(),
|
surface_to_output: HashMap::new(),
|
||||||
output_to_handle: HashMap::new(),
|
|
||||||
_pointer: pointer,
|
_pointer: pointer,
|
||||||
shared_pointer_serial: shared_serial,
|
shared_pointer_serial: shared_serial,
|
||||||
active_output: None,
|
|
||||||
primary_output: None,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -42,61 +39,48 @@ impl AppState {
|
||||||
main_surface_id: ObjectId,
|
main_surface_id: ObjectId,
|
||||||
window: PerOutputWindow,
|
window: PerOutputWindow,
|
||||||
) {
|
) {
|
||||||
let key = OutputKey::new(&output_id);
|
let handle = self.output_mapping.insert(output_id);
|
||||||
let handle = key.handle();
|
|
||||||
self.output_to_handle.insert(output_id, handle);
|
|
||||||
self.surface_to_output.insert(main_surface_id, handle);
|
self.surface_to_output.insert(main_surface_id, handle);
|
||||||
|
|
||||||
let is_primary = self.primary_output.is_none();
|
let is_primary = self.output_registry.is_empty();
|
||||||
if is_primary {
|
|
||||||
self.primary_output = Some(handle);
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut info = OutputInfo::new(handle);
|
let mut info = OutputInfo::new(handle);
|
||||||
info.set_primary(is_primary);
|
info.set_primary(is_primary);
|
||||||
self.output_info.insert(handle, info);
|
|
||||||
|
|
||||||
self.outputs.insert(handle, window);
|
self.output_registry.add(info);
|
||||||
}
|
self.windows.insert(handle, window);
|
||||||
|
|
||||||
pub fn get_output_by_key(&self, key: &OutputKey) -> Option<&PerOutputWindow> {
|
|
||||||
self.outputs.get(&key.handle())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_output_by_key_mut(&mut self, key: &OutputKey) -> Option<&mut PerOutputWindow> {
|
|
||||||
self.outputs.get_mut(&key.handle())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_output_by_handle(&self, handle: OutputHandle) -> Option<&PerOutputWindow> {
|
pub fn get_output_by_handle(&self, handle: OutputHandle) -> Option<&PerOutputWindow> {
|
||||||
self.outputs.get(&handle)
|
self.windows.get(&handle)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_output_by_handle_mut(
|
pub fn get_output_by_handle_mut(
|
||||||
&mut self,
|
&mut self,
|
||||||
handle: OutputHandle,
|
handle: OutputHandle,
|
||||||
) -> Option<&mut PerOutputWindow> {
|
) -> Option<&mut PerOutputWindow> {
|
||||||
self.outputs.get_mut(&handle)
|
self.windows.get_mut(&handle)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_output_by_output_id(&self, output_id: &ObjectId) -> Option<&PerOutputWindow> {
|
pub fn get_output_by_output_id(&self, output_id: &ObjectId) -> Option<&PerOutputWindow> {
|
||||||
self.output_to_handle
|
self.output_mapping
|
||||||
.get(output_id)
|
.get(output_id)
|
||||||
.and_then(|handle| self.outputs.get(handle))
|
.and_then(|handle| self.windows.get(&handle))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_output_by_output_id_mut(
|
pub fn get_output_by_output_id_mut(
|
||||||
&mut self,
|
&mut self,
|
||||||
output_id: &ObjectId,
|
output_id: &ObjectId,
|
||||||
) -> Option<&mut PerOutputWindow> {
|
) -> Option<&mut PerOutputWindow> {
|
||||||
self.output_to_handle
|
self.output_mapping
|
||||||
.get(output_id)
|
.get(output_id)
|
||||||
.and_then(|handle| self.outputs.get_mut(handle))
|
.and_then(|handle| self.windows.get_mut(&handle))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_output_by_surface(&self, surface_id: &ObjectId) -> Option<&PerOutputWindow> {
|
pub fn get_output_by_surface(&self, surface_id: &ObjectId) -> Option<&PerOutputWindow> {
|
||||||
self.surface_to_output
|
self.surface_to_output
|
||||||
.get(surface_id)
|
.get(surface_id)
|
||||||
.and_then(|handle| self.outputs.get(handle))
|
.and_then(|handle| self.windows.get(handle))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_output_by_surface_mut(
|
pub fn get_output_by_surface_mut(
|
||||||
|
|
@ -105,78 +89,69 @@ impl AppState {
|
||||||
) -> Option<&mut PerOutputWindow> {
|
) -> Option<&mut PerOutputWindow> {
|
||||||
self.surface_to_output
|
self.surface_to_output
|
||||||
.get(surface_id)
|
.get(surface_id)
|
||||||
.and_then(|handle| self.outputs.get_mut(handle))
|
.and_then(|handle| self.windows.get_mut(handle))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_output_by_layer_surface_mut(
|
pub fn get_output_by_layer_surface_mut(
|
||||||
&mut self,
|
&mut self,
|
||||||
layer_surface_id: &ObjectId,
|
layer_surface_id: &ObjectId,
|
||||||
) -> Option<&mut PerOutputWindow> {
|
) -> Option<&mut PerOutputWindow> {
|
||||||
self.outputs
|
self.windows
|
||||||
.values_mut()
|
.values_mut()
|
||||||
.find(|window| window.layer_surface().as_ref().id() == *layer_surface_id)
|
.find(|window| window.layer_surface().as_ref().id() == *layer_surface_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_key_by_surface(&self, surface_id: &ObjectId) -> Option<OutputKey> {
|
|
||||||
self.surface_to_output
|
|
||||||
.get(surface_id)
|
|
||||||
.map(|&handle| OutputKey::from(handle))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_key_by_output_id(&self, output_id: &ObjectId) -> Option<OutputKey> {
|
|
||||||
self.output_to_handle
|
|
||||||
.get(output_id)
|
|
||||||
.map(|&handle| OutputKey::from(handle))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_handle_by_surface(&self, surface_id: &ObjectId) -> Option<OutputHandle> {
|
pub fn get_handle_by_surface(&self, surface_id: &ObjectId) -> Option<OutputHandle> {
|
||||||
self.surface_to_output.get(surface_id).copied()
|
self.surface_to_output.get(surface_id).copied()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_handle_by_output_id(&self, output_id: &ObjectId) -> Option<OutputHandle> {
|
pub fn get_handle_by_output_id(&self, output_id: &ObjectId) -> Option<OutputHandle> {
|
||||||
self.output_to_handle.get(output_id).copied()
|
self.output_mapping.get(output_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn register_popup_surface(&mut self, popup_surface_id: ObjectId, output_key: OutputKey) {
|
pub fn register_popup_surface(
|
||||||
|
&mut self,
|
||||||
|
popup_surface_id: ObjectId,
|
||||||
|
output_handle: OutputHandle,
|
||||||
|
) {
|
||||||
self.surface_to_output
|
self.surface_to_output
|
||||||
.insert(popup_surface_id, output_key.handle());
|
.insert(popup_surface_id, output_handle);
|
||||||
}
|
|
||||||
|
|
||||||
pub fn set_active_output(&mut self, key: Option<OutputKey>) {
|
|
||||||
self.active_output = key.map(|k| k.handle());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_active_output_handle(&mut self, handle: Option<OutputHandle>) {
|
pub fn set_active_output_handle(&mut self, handle: Option<OutputHandle>) {
|
||||||
self.active_output = handle;
|
self.output_registry.set_active(handle);
|
||||||
}
|
|
||||||
|
|
||||||
pub fn active_output(&self) -> Option<OutputKey> {
|
|
||||||
self.active_output.map(OutputKey::from)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn active_output_handle(&self) -> Option<OutputHandle> {
|
pub fn active_output_handle(&self) -> Option<OutputHandle> {
|
||||||
self.active_output
|
self.output_registry.active_handle()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn primary_output(&self) -> Option<&PerOutputWindow> {
|
pub fn primary_output(&self) -> Option<&PerOutputWindow> {
|
||||||
self.primary_output
|
self.output_registry
|
||||||
.and_then(|handle| self.outputs.get(&handle))
|
.primary_handle()
|
||||||
|
.and_then(|handle| self.windows.get(&handle))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn primary_output_handle(&self) -> Option<OutputHandle> {
|
pub fn primary_output_handle(&self) -> Option<OutputHandle> {
|
||||||
self.primary_output
|
self.output_registry.primary_handle()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn active_output(&self) -> Option<&PerOutputWindow> {
|
||||||
|
self.output_registry
|
||||||
|
.active_handle()
|
||||||
|
.and_then(|handle| self.windows.get(&handle))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn all_outputs(&self) -> impl Iterator<Item = &PerOutputWindow> {
|
pub fn all_outputs(&self) -> impl Iterator<Item = &PerOutputWindow> {
|
||||||
self.outputs.values()
|
self.windows.values()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn all_outputs_mut(&mut self) -> impl Iterator<Item = &mut PerOutputWindow> {
|
pub fn all_outputs_mut(&mut self) -> impl Iterator<Item = &mut PerOutputWindow> {
|
||||||
self.outputs.values_mut()
|
self.windows.values_mut()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn outputs_with_handles(&self) -> impl Iterator<Item = (OutputHandle, &PerOutputWindow)> {
|
pub fn outputs_with_handles(&self) -> impl Iterator<Item = (OutputHandle, &PerOutputWindow)> {
|
||||||
self.outputs
|
self.windows
|
||||||
.iter()
|
.iter()
|
||||||
.map(|(&handle, window)| (handle, window))
|
.map(|(&handle, window)| (handle, window))
|
||||||
}
|
}
|
||||||
|
|
@ -186,7 +161,7 @@ impl AppState {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn find_output_by_popup(&self, popup_surface_id: &ObjectId) -> Option<&PerOutputWindow> {
|
pub fn find_output_by_popup(&self, popup_surface_id: &ObjectId) -> Option<&PerOutputWindow> {
|
||||||
self.outputs.values().find(|window| {
|
self.windows.values().find(|window| {
|
||||||
window
|
window
|
||||||
.popup_manager()
|
.popup_manager()
|
||||||
.as_ref()
|
.as_ref()
|
||||||
|
|
@ -199,7 +174,7 @@ impl AppState {
|
||||||
&mut self,
|
&mut self,
|
||||||
popup_surface_id: &ObjectId,
|
popup_surface_id: &ObjectId,
|
||||||
) -> Option<&mut PerOutputWindow> {
|
) -> Option<&mut PerOutputWindow> {
|
||||||
self.outputs.values_mut().find(|window| {
|
self.windows.values_mut().find(|window| {
|
||||||
window
|
window
|
||||||
.popup_manager()
|
.popup_manager()
|
||||||
.as_ref()
|
.as_ref()
|
||||||
|
|
@ -208,18 +183,8 @@ impl AppState {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_key_by_popup(&self, popup_surface_id: &ObjectId) -> Option<OutputKey> {
|
|
||||||
self.outputs.iter().find_map(|(&handle, window)| {
|
|
||||||
window
|
|
||||||
.popup_manager()
|
|
||||||
.as_ref()
|
|
||||||
.and_then(|pm| pm.find_by_surface(popup_surface_id))
|
|
||||||
.map(|_| OutputKey::from(handle))
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_handle_by_popup(&self, popup_surface_id: &ObjectId) -> Option<OutputHandle> {
|
pub fn get_handle_by_popup(&self, popup_surface_id: &ObjectId) -> Option<OutputHandle> {
|
||||||
self.outputs.iter().find_map(|(&handle, window)| {
|
self.windows.iter().find_map(|(&handle, window)| {
|
||||||
window
|
window
|
||||||
.popup_manager()
|
.popup_manager()
|
||||||
.as_ref()
|
.as_ref()
|
||||||
|
|
@ -229,20 +194,24 @@ impl AppState {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_output_info(&self, handle: OutputHandle) -> Option<&OutputInfo> {
|
pub fn get_output_info(&self, handle: OutputHandle) -> Option<&OutputInfo> {
|
||||||
self.output_info.get(&handle)
|
self.output_registry.get(handle)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_output_info_mut(&mut self, handle: OutputHandle) -> Option<&mut OutputInfo> {
|
pub fn get_output_info_mut(&mut self, handle: OutputHandle) -> Option<&mut OutputInfo> {
|
||||||
self.output_info.get_mut(&handle)
|
self.output_registry.get_mut(handle)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn all_output_info(&self) -> impl Iterator<Item = &OutputInfo> {
|
pub fn all_output_info(&self) -> impl Iterator<Item = &OutputInfo> {
|
||||||
self.output_info.values()
|
self.output_registry.all_info()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn outputs_with_info(&self) -> impl Iterator<Item = (&OutputInfo, &PerOutputWindow)> {
|
pub fn outputs_with_info(&self) -> impl Iterator<Item = (&OutputInfo, &PerOutputWindow)> {
|
||||||
self.output_info
|
self.output_registry
|
||||||
.iter()
|
.all()
|
||||||
.filter_map(|(handle, info)| self.outputs.get(handle).map(|window| (info, window)))
|
.filter_map(|(handle, info)| self.windows.get(&handle).map(|window| (info, window)))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub const fn output_registry(&self) -> &OutputRegistry {
|
||||||
|
&self.output_registry
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ use std::result::Result as StdResult;
|
||||||
pub use builder::LayerShika;
|
pub use builder::LayerShika;
|
||||||
pub use layer_shika_adapters::PopupWindow;
|
pub use layer_shika_adapters::PopupWindow;
|
||||||
pub use layer_shika_adapters::platform::{slint, slint_interpreter};
|
pub use layer_shika_adapters::platform::{slint, slint_interpreter};
|
||||||
|
pub use layer_shika_domain::entities::output_registry::OutputRegistry;
|
||||||
pub use layer_shika_domain::value_objects::anchor::AnchorEdges;
|
pub use layer_shika_domain::value_objects::anchor::AnchorEdges;
|
||||||
pub use layer_shika_domain::value_objects::keyboard_interactivity::KeyboardInteractivity;
|
pub use layer_shika_domain::value_objects::keyboard_interactivity::KeyboardInteractivity;
|
||||||
pub use layer_shika_domain::value_objects::layer::Layer;
|
pub use layer_shika_domain::value_objects::layer::Layer;
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ use layer_shika_adapters::{
|
||||||
AppState, PopupManager, WaylandWindowConfig, WindowState, WindowingSystemFacade,
|
AppState, PopupManager, WaylandWindowConfig, WindowState, WindowingSystemFacade,
|
||||||
};
|
};
|
||||||
use layer_shika_domain::config::WindowConfig;
|
use layer_shika_domain::config::WindowConfig;
|
||||||
|
use layer_shika_domain::entities::output_registry::OutputRegistry;
|
||||||
use layer_shika_domain::errors::DomainError;
|
use layer_shika_domain::errors::DomainError;
|
||||||
use layer_shika_domain::value_objects::output_handle::OutputHandle;
|
use layer_shika_domain::value_objects::output_handle::OutputHandle;
|
||||||
use layer_shika_domain::value_objects::output_info::OutputInfo;
|
use layer_shika_domain::value_objects::output_info::OutputInfo;
|
||||||
|
|
@ -141,6 +142,10 @@ impl RuntimeState<'_> {
|
||||||
.map(WindowState::component_instance)
|
.map(WindowState::component_instance)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub const fn output_registry(&self) -> &OutputRegistry {
|
||||||
|
self.app_state.output_registry()
|
||||||
|
}
|
||||||
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn primary_output_handle(&self) -> Option<OutputHandle> {
|
pub fn primary_output_handle(&self) -> Option<OutputHandle> {
|
||||||
self.app_state.primary_output_handle()
|
self.app_state.primary_output_handle()
|
||||||
|
|
@ -180,7 +185,6 @@ impl RuntimeState<'_> {
|
||||||
fn active_or_primary_output(&self) -> Option<&WindowState> {
|
fn active_or_primary_output(&self) -> Option<&WindowState> {
|
||||||
self.app_state
|
self.app_state
|
||||||
.active_output()
|
.active_output()
|
||||||
.and_then(|key| self.app_state.get_output_by_key(&key))
|
|
||||||
.or_else(|| self.app_state.primary_output())
|
.or_else(|| self.app_state.primary_output())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -579,4 +583,10 @@ impl WindowingSystem {
|
||||||
let system = facade.inner_ref();
|
let system = facade.inner_ref();
|
||||||
system.app_state().all_output_info().cloned().collect()
|
system.app_state().all_output_info().cloned().collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn output_registry(&self) -> OutputRegistry {
|
||||||
|
let facade = self.inner.borrow();
|
||||||
|
let system = facade.inner_ref();
|
||||||
|
system.app_state().output_registry().clone()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
pub mod component;
|
pub mod component;
|
||||||
|
pub mod output_registry;
|
||||||
pub mod surface;
|
pub mod surface;
|
||||||
pub mod window;
|
pub mod window;
|
||||||
|
|
|
||||||
156
crates/domain/src/entities/output_registry.rs
Normal file
156
crates/domain/src/entities/output_registry.rs
Normal file
|
|
@ -0,0 +1,156 @@
|
||||||
|
use crate::value_objects::output_handle::OutputHandle;
|
||||||
|
use crate::value_objects::output_info::OutputInfo;
|
||||||
|
use crate::value_objects::output_policy::OutputPolicy;
|
||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct OutputRegistry {
|
||||||
|
outputs: HashMap<OutputHandle, OutputInfo>,
|
||||||
|
primary_output: Option<OutputHandle>,
|
||||||
|
active_output: Option<OutputHandle>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl OutputRegistry {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
outputs: HashMap::new(),
|
||||||
|
primary_output: None,
|
||||||
|
active_output: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn add(&mut self, info: OutputInfo) -> OutputHandle {
|
||||||
|
let handle = info.handle();
|
||||||
|
let is_first = self.outputs.is_empty();
|
||||||
|
|
||||||
|
self.outputs.insert(handle, info);
|
||||||
|
|
||||||
|
if is_first {
|
||||||
|
self.primary_output = Some(handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
handle
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn remove(&mut self, handle: OutputHandle) -> Option<OutputInfo> {
|
||||||
|
let info = self.outputs.remove(&handle);
|
||||||
|
|
||||||
|
if self.primary_output == Some(handle) {
|
||||||
|
self.primary_output = self.outputs.keys().next().copied();
|
||||||
|
}
|
||||||
|
|
||||||
|
if self.active_output == Some(handle) {
|
||||||
|
self.active_output = None;
|
||||||
|
}
|
||||||
|
|
||||||
|
info
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get(&self, handle: OutputHandle) -> Option<&OutputInfo> {
|
||||||
|
self.outputs.get(&handle)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_mut(&mut self, handle: OutputHandle) -> Option<&mut OutputInfo> {
|
||||||
|
self.outputs.get_mut(&handle)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn find_by_name(&self, name: &str) -> Option<(OutputHandle, &OutputInfo)> {
|
||||||
|
self.outputs
|
||||||
|
.iter()
|
||||||
|
.find(|(_, info)| info.name() == Some(name))
|
||||||
|
.map(|(handle, info)| (*handle, info))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn find_by_model(&self, model: &str) -> Option<(OutputHandle, &OutputInfo)> {
|
||||||
|
self.outputs
|
||||||
|
.iter()
|
||||||
|
.find(|(_, info)| info.geometry().and_then(|g| g.model.as_deref()) == Some(model))
|
||||||
|
.map(|(handle, info)| (*handle, info))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn all(&self) -> impl Iterator<Item = (OutputHandle, &OutputInfo)> {
|
||||||
|
self.outputs.iter().map(|(handle, info)| (*handle, info))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn all_info(&self) -> impl Iterator<Item = &OutputInfo> {
|
||||||
|
self.outputs.values()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn primary(&self) -> Option<(OutputHandle, &OutputInfo)> {
|
||||||
|
self.primary_output
|
||||||
|
.and_then(|handle| self.outputs.get(&handle).map(|info| (handle, info)))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn primary_handle(&self) -> Option<OutputHandle> {
|
||||||
|
self.primary_output
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn active(&self) -> Option<(OutputHandle, &OutputInfo)> {
|
||||||
|
self.active_output
|
||||||
|
.and_then(|handle| self.outputs.get(&handle).map(|info| (handle, info)))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn active_handle(&self) -> Option<OutputHandle> {
|
||||||
|
self.active_output
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn active_or_primary(&self) -> Option<(OutputHandle, &OutputInfo)> {
|
||||||
|
self.active().or_else(|| self.primary())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn active_or_primary_handle(&self) -> Option<OutputHandle> {
|
||||||
|
self.active_output.or(self.primary_output)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_active(&mut self, handle: Option<OutputHandle>) {
|
||||||
|
if let Some(h) = handle {
|
||||||
|
if self.outputs.contains_key(&h) {
|
||||||
|
self.active_output = Some(h);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
self.active_output = None;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_primary(&mut self, handle: OutputHandle) -> bool {
|
||||||
|
if !self.outputs.contains_key(&handle) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(old_primary) = self.primary_output {
|
||||||
|
if let Some(old_info) = self.outputs.get_mut(&old_primary) {
|
||||||
|
old_info.set_primary(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
self.primary_output = Some(handle);
|
||||||
|
|
||||||
|
if let Some(new_info) = self.outputs.get_mut(&handle) {
|
||||||
|
new_info.set_primary(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn select_by_policy(&self, policy: &OutputPolicy) -> Vec<(OutputHandle, &OutputInfo)> {
|
||||||
|
self.outputs
|
||||||
|
.iter()
|
||||||
|
.filter(|(_, info)| policy.should_render(info))
|
||||||
|
.map(|(handle, info)| (*handle, info))
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn count(&self) -> usize {
|
||||||
|
self.outputs.len()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn is_empty(&self) -> bool {
|
||||||
|
self.outputs.is_empty()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for OutputRegistry {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self::new()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
pub mod config;
|
pub mod config;
|
||||||
pub mod dimensions;
|
pub mod dimensions;
|
||||||
pub(crate) mod entities;
|
pub mod entities;
|
||||||
pub mod errors;
|
pub mod errors;
|
||||||
pub mod ports;
|
pub mod ports;
|
||||||
pub mod prelude;
|
pub mod prelude;
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ pub use crate::dimensions::{
|
||||||
LogicalPosition, LogicalSize, PhysicalPosition, PhysicalSize, ScaleFactor,
|
LogicalPosition, LogicalSize, PhysicalPosition, PhysicalSize, ScaleFactor,
|
||||||
};
|
};
|
||||||
pub use crate::entities::component::UiComponentHandle;
|
pub use crate::entities::component::UiComponentHandle;
|
||||||
|
pub use crate::entities::output_registry::OutputRegistry;
|
||||||
pub use crate::entities::surface::SurfaceHandle;
|
pub use crate::entities::surface::SurfaceHandle;
|
||||||
pub use crate::entities::window::WindowHandle;
|
pub use crate::entities::window::WindowHandle;
|
||||||
pub use crate::errors::{DomainError, Result};
|
pub use crate::errors::{DomainError, Result};
|
||||||
|
|
|
||||||
|
|
@ -46,7 +46,7 @@ pub mod prelude;
|
||||||
|
|
||||||
pub use layer_shika_composition::{
|
pub use layer_shika_composition::{
|
||||||
AnchorEdges, Error, EventLoopHandle, KeyboardInteractivity, Layer, LayerShika, OutputGeometry,
|
AnchorEdges, Error, EventLoopHandle, KeyboardInteractivity, Layer, LayerShika, OutputGeometry,
|
||||||
OutputHandle, OutputInfo, OutputPolicy, PopupAt, PopupHandle, PopupPositioningMode,
|
OutputHandle, OutputInfo, OutputPolicy, OutputRegistry, PopupAt, PopupHandle, PopupPositioningMode,
|
||||||
PopupRequest, PopupSize, PopupWindow, Result, RuntimeState, SlintCallbackContract,
|
PopupRequest, PopupSize, PopupWindow, Result, RuntimeState, SlintCallbackContract,
|
||||||
SlintCallbackNames, WindowingSystem,
|
SlintCallbackNames, WindowingSystem,
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ pub use crate::{
|
||||||
// Domain value objects
|
// Domain value objects
|
||||||
pub use crate::{
|
pub use crate::{
|
||||||
AnchorEdges, KeyboardInteractivity, Layer, OutputGeometry, OutputHandle, OutputInfo,
|
AnchorEdges, KeyboardInteractivity, Layer, OutputGeometry, OutputHandle, OutputInfo,
|
||||||
OutputPolicy, PopupAt, PopupHandle, PopupPositioningMode, PopupRequest, PopupSize,
|
OutputPolicy, OutputRegistry, PopupAt, PopupHandle, PopupPositioningMode, PopupRequest, PopupSize,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Event loop types
|
// Event loop types
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue