Skip to main content

cast_spell

Macro cast_spell 

Source
macro_rules! cast_spell {
    (
        $win:expr
        $(, notification: $noti:expr)?
        $(,)?
    ) => { ... };
    (
        ($win:expr, ipc)
        $(, notification: $noti:expr)?
        $(,)?
    ) => { ... };
    (
        windows: [ $($entry:tt),+ $(,)? ]
        $(, notification: $noti:expr)?
        $(,)?
    ) => { ... };
    (
        windows: $windows:expr
        $(, windows_ipc: $windows_ipc:expr)?
        $(, Notification: $noti:expr)?
        $(,)?
    ) => { ... };
    (
        @expand
        entry: ($waywindow:expr, ipc)
    ) => { ... };
    (
        @expand
        entry: $waywindow:expr
    ) => { ... };
    (@vector_add $wins:expr, ($waywindow:expr, ipc)) => { ... };
    (@vector_add $wins:expr, $waywindow:expr) => { ... };
    (@name ($win:expr,ipc)) => { ... };
    (@name $win:expr) => { ... };
    (@notification $noti:expr) => { ... };
    (@run $way:expr) => { ... };
    (lock: $lock:expr) => { ... };
}
Expand description

It is a macro which builds upon the internal functions of spell to create and start an event loop. This macro is responsible for the creation of necessary bindings before running the code.

cast_spell uses a combination of internal functions that are not to be used by the end user. This macro also generates the code for IPC control. In future, it will be added with a way to control logging also. It is also creates so that when optional services are created, they could be easily integrated into the system. So, you can optionally define these adapters and listeners rather than having to pass them to a function filled with arguments wrapped in Option. This page defines the various ways in which the macro is capable of taking in windows.

It is important to note that passing values that are not documented here can lead to unexpected issues and errors.

§Single window

// window here is generated from generate_widgets macro.
cast_spell!(winodw)
cast_spell!((window, ipc))

If you want to specify that window also supports remote IPC, then it should be wrapped in parenthesis like this (_, ipc). In that case, it should also implement IpcController. The most basic way in which spell can be used is passing a single widget to it. This method is common if you use spell for a specific widget or you have compressed whole shell in a single widget (It is possible and rather efficient).

§Multiple windows

cast_spell!(windows: [win1, win2, (win3, ipc)])

This method is used if there are multiple widgets and their number is known during compilation time. This requires that windows be generated from the generate_widgets macro. You can pass them directly or within parenthesis as written if they implement IPC trait. I have began to notice that previously, when vector was passed for the given windows. Then a unique approach was used, where number of windows was calculated dynamically for number of monitors. With this method, that is not possible.

You can not do this here as the struct are generated dynamically by generate_widgets and vector can hold data of same types only. As a result, every window generated by generate_widgets implements the dash dash trait. As a result, passing values to it can also be done by creating a vector or type Vec<Box<dyn Traitname>>.

But in this case values implementing IPC can’t not be passed along with it. So, they are passed separately. Following is the code example.

cast_spell!(windows: windows_vector, windows_ipc: windows_ipc_vector)

If there is no window implementing the IPC trait. windows_ipc can be ignored as following, but windows need to be passed with a vector containing at least a single widget.

cast_spell!(windows: windows_vector)

§Optional Arguments

This is the biggest reason for using a macro instead of a function. It gives the flexibility for defining values optionally. Currently, there is only following values that can be specified. The key and requirement over input values is defined below.

  1. notification: value should implement NotificationHandler.

It is important to note that optional values can only be defined when passing single and multiple widgets. Example for all the optional values is defined below.

cast_spell!(window,
  notification: noti_window // Optional
)

§Lock screen

Lock screen can also be defined by the macro. Since, the event loop of a lock screen terminates after teh lock is unlocked. The lock can never be used and initialised with other optional values and windows. As a result, it is needed to be defined and used in a separate binary. More on this can be found in documentation of SpellLock. Soon, functionality of lock will all be include in generate_widgets and SpellLock will become internal.

Example code snippet.

cast_spell!(lock: lock_window)