Skip to content

Commit

Permalink
feat: support record mainwindow
Browse files Browse the repository at this point in the history
  • Loading branch information
Decodetalkers committed Dec 5, 2024
1 parent 8e5bc54 commit 19d93a5
Show file tree
Hide file tree
Showing 6 changed files with 88 additions and 22 deletions.
6 changes: 6 additions & 0 deletions iced_examples/counter_mulit_pattern/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ enum WindowInfo {
#[singleton]
Right,
PopUp,
#[main]
Main,
}

#[derive(Debug, Clone, Copy)]
Expand Down Expand Up @@ -101,6 +103,10 @@ impl Counter {
}

fn set_id_info(&mut self, id: iced::window::Id, info: WindowInfo) {
if let WindowInfo::Main = info {
println!("it is main window: {id}");
return;
}
self.ids.insert(id, info);
}

Expand Down
9 changes: 9 additions & 0 deletions iced_layershell/src/actions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,15 @@ pub trait IsSingleton {
}
}

pub struct MainWindowInfo;

impl TryFrom<MainWindowInfo> for () {
type Error = ();
fn try_from(_: MainWindowInfo) -> Result<(), Self::Error> {
Err(())
}
}

impl IsSingleton for () {}

#[derive(Debug, PartialEq, Eq, Clone, Copy)]
Expand Down
11 changes: 7 additions & 4 deletions iced_layershell/src/build_pattern/daemon.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use std::borrow::Cow;
use iced::Font;
use iced::{Element, Task};

use crate::actions::{IsSingleton, LayershellCustomActionsWithIdAndInfo};
use crate::actions::{IsSingleton, LayershellCustomActionsWithIdAndInfo, MainWindowInfo};

use crate::settings::LayerShellSettings;
use crate::DefaultStyle;
Expand All @@ -27,7 +27,10 @@ pub trait Program: Sized {
type State;
type Renderer: Renderer;

type WindowInfo: Clone + PartialEq + IsSingleton;
type WindowInfo: Clone
+ PartialEq
+ IsSingleton
+ TryFrom<MainWindowInfo, Error = ()>;
/// The type of __messages__ your [`Application`] will produce.
type Message: std::fmt::Debug
+ Send
Expand Down Expand Up @@ -361,7 +364,7 @@ pub fn daemon<State, Message, Theme, Renderer, WindowInfo>(
) -> Daemon<impl Program<Message = Message, Theme = Theme, State = State, WindowInfo = WindowInfo>>
where
State: 'static,
WindowInfo: Clone + PartialEq + IsSingleton,
WindowInfo: Clone + PartialEq + IsSingleton + TryFrom<MainWindowInfo, Error = ()>,
Message: 'static
+ TryInto<LayershellCustomActionsWithIdAndInfo<WindowInfo>, Error = Message>
+ Send
Expand Down Expand Up @@ -418,7 +421,7 @@ where
WindowInfo,
>
where
WindowInfo: Clone + PartialEq + IsSingleton,
WindowInfo: Clone + PartialEq + IsSingleton + TryFrom<MainWindowInfo, Error = ()>,
Message: 'static
+ TryInto<LayershellCustomActionsWithIdAndInfo<WindowInfo>, Error = Message>
+ Send
Expand Down
4 changes: 3 additions & 1 deletion iced_layershell/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ pub mod reexport {
pub use layershellev::NewLayerShellSettings;
}

use actions::MainWindowInfo;
use actions::{IsSingleton, LayershellCustomActions, LayershellCustomActionsWithIdAndInfo};
use settings::Settings;

Expand Down Expand Up @@ -358,7 +359,8 @@ pub trait MultiApplication: Sized {
fn run(settings: Settings<Self::Flags>) -> Result
where
Self: 'static,
<Self as MultiApplication>::WindowInfo: Clone + PartialEq + IsSingleton,
<Self as MultiApplication>::WindowInfo:
Clone + PartialEq + IsSingleton + TryFrom<MainWindowInfo, Error = ()>,
Self::Message: 'static
+ TryInto<LayershellCustomActionsWithIdAndInfo<Self::WindowInfo>, Error = Self::Message>,
{
Expand Down
49 changes: 33 additions & 16 deletions iced_layershell/src/multi_window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ mod state;
use crate::{
actions::{
IcedNewMenuSettings, IcedNewPopupSettings, IsSingleton, LayerShellActionVec,
LayershellCustomActionsWithIdAndInfo, LayershellCustomActionsWithIdInner, MenuDirection,
LayershellCustomActionsWithIdAndInfo, LayershellCustomActionsWithIdInner, MainWindowInfo,
MenuDirection,
},
multi_window::window_manager::WindowManager,
settings::VirtualKeyboardSettings,
Expand Down Expand Up @@ -156,7 +157,8 @@ where
E: Executor + 'static,
C: Compositor<Renderer = A::Renderer> + 'static,
A::Theme: DefaultStyle,
<A as Application>::WindowInfo: Clone + PartialEq + IsSingleton,
<A as Application>::WindowInfo:
Clone + PartialEq + IsSingleton + TryFrom<MainWindowInfo, Error = ()>,
A::Message:
'static + TryInto<LayershellCustomActionsWithIdAndInfo<A::WindowInfo>, Error = A::Message>,
{
Expand Down Expand Up @@ -489,7 +491,7 @@ async fn run_instance<A, E, C>(
E: Executor + 'static,
C: Compositor<Renderer = A::Renderer> + 'static,
A::Theme: DefaultStyle,
A::WindowInfo: Clone + PartialEq + IsSingleton,
A::WindowInfo: Clone + PartialEq + IsSingleton + TryFrom<MainWindowInfo, Error = ()>,
A::Message:
'static + TryInto<LayershellCustomActionsWithIdAndInfo<A::WindowInfo>, Error = A::Message>,
{
Expand Down Expand Up @@ -663,19 +665,34 @@ async fn run_instance<A, E, C>(
}
}

if is_created && is_new_window {
let cached_interfaces: HashMap<window::Id, user_interface::Cache> =
ManuallyDrop::into_inner(user_interfaces)
.drain()
.map(|(id, ui)| (id, ui.into_cache()))
.collect();
application.set_id_info(id, info.unwrap().clone());
user_interfaces = ManuallyDrop::new(build_user_interfaces(
&application,
&mut debug,
&mut window_manager,
cached_interfaces,
));
if is_new_window {
if is_created {
let cached_interfaces: HashMap<window::Id, user_interface::Cache> =
ManuallyDrop::into_inner(user_interfaces)
.drain()
.map(|(id, ui)| (id, ui.into_cache()))
.collect();
application.set_id_info(id, info.unwrap().clone());
user_interfaces = ManuallyDrop::new(build_user_interfaces(
&application,
&mut debug,
&mut window_manager,
cached_interfaces,
));
} else if let Ok(info) = MainWindowInfo.try_into() {
let cached_interfaces: HashMap<window::Id, user_interface::Cache> =
ManuallyDrop::into_inner(user_interfaces)
.drain()
.map(|(id, ui)| (id, ui.into_cache()))
.collect();
application.set_id_info(id, info);
user_interfaces = ManuallyDrop::new(build_user_interfaces(
&application,
&mut debug,
&mut window_manager,
cached_interfaces,
));
}
}
}
MultiWindowIcedLayerEvent(None, IcedLayerEvent::Window(event)) => {
Expand Down
31 changes: 30 additions & 1 deletion iced_layershell_macros/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,12 @@ fn is_singleton_attr(attr: &Attribute) -> bool {
attr.path().is_ident("singleton")
}

#[proc_macro_derive(LayerSingleton, attributes(singleton))]
#[inline]
fn is_mainwindow_attr(attr: &Attribute) -> bool {
attr.path().is_ident("main")
}

#[proc_macro_derive(LayerSingleton, attributes(singleton, main))]
pub fn layer_singleton(input: TokenStream) -> TokenStream {
// Parse the input as a DeriveInput
let input = parse_macro_input!(input as DeriveInput);
Expand Down Expand Up @@ -48,6 +53,29 @@ pub fn layer_singleton(input: TokenStream) -> TokenStream {
}
});

let try_from_mainwindow = variants
.iter()
.find(|variant| variant.attrs.iter().any(is_mainwindow_attr))
.map(|variant| {
let variant_name = &variant.ident;
quote! {
impl TryFrom<iced_layershell::actions::MainWindowInfo> for #name {
type Error = ();
fn try_from(_val: iced_layershell::actions::MainWindowInfo) -> Result<Self, ()> {
Ok(Self::#variant_name)
}
}
}
})
.unwrap_or(quote! {
impl TryFrom<iced_layershell::actions::MainWindowInfo> for #name {
type Error = ();
fn try_from(_val: iced_layershell::actions::MainWindowInfo) -> Result<Self, ()> {
Err(())
}
}
});

// Generate the final implementation
let expanded = quote! {
impl iced_layershell::actions::IsSingleton for #name {
Expand All @@ -57,6 +85,7 @@ pub fn layer_singleton(input: TokenStream) -> TokenStream {
}
}
}
#try_from_mainwindow
};

TokenStream::from(expanded)
Expand Down

0 comments on commit 19d93a5

Please sign in to comment.