Skip to content

Commit

Permalink
refactor(vd): add strategy pattern to virtual desktops
Browse files Browse the repository at this point in the history
  • Loading branch information
eythaann committed Aug 27, 2024
1 parent 185a71b commit e8eaed7
Show file tree
Hide file tree
Showing 111 changed files with 3,448 additions and 2,241 deletions.
4 changes: 4 additions & 0 deletions changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@
## [Unreleased]
### features
- add volume changed popup.
- new custom virtual desktop implementation.

### refactor
- add strategy pattern to virtual desktops

## [1.9.11]
### features
Expand Down
78 changes: 44 additions & 34 deletions documentation/project.md
Original file line number Diff line number Diff line change
@@ -1,34 +1,44 @@
# Welcome to the Seelen UI Project

Welcome to the Seelen UI project! This guide will help you get started with the codebase and understand its structure.

## Languages Used
This project utilizes the following languages:
- **Rust**
- **TypeScript**
- **PowerShell** (in special cases)

## Getting Started
To run this project, follow these steps:

1. [Install Rust](https://www.rust-lang.org/tools/install).
2. Run the following commands:

```bash
npm install && npm run dev
```

This will set up the project similarly to any other Node.js project, with the added step of installing Rust first.

## Architecture

### Views Architecture

The `src\apps` folder contains views that follow Hexagonal Architecture. Each folder in `src\apps` represents a view (excluding shared). These views are independent web pages bundled with `esbuild`. While any technology or library can be used in a view, most are based on `React` and `Redux`.

#### Shared Folder
Following Hexagonal Architecture, the `shared` folder contains utilities, schemas, and other shared resources used across multiple views.

### Background Architecture

The `src\background` folder does not follow a specific architecture but is based on Events Architecture.
# Welcome to the Seelen UI Project

Welcome to the Seelen UI project! This guide will help you get started with the codebase and understand its structure.

## Languages Used
This project utilizes the following languages:
- **Rust**
- **TypeScript**
- **PowerShell** (in special cases)

## Getting Started
To run this project, follow these steps:

1. [Install Rust](https://www.rust-lang.org/tools/install).
2. Run the following commands:

```bash
npm install && npm run dev
```

This will set up the project similarly to any other Node.js project, with the added step of installing Rust first.

## Architecture

### Views Architecture

The `src\apps` folder contains views that follow Hexagonal Architecture. Each folder in `src\apps` represents a view (excluding shared). These views are independent web pages bundled with `esbuild`. While any technology or library can be used in a view, most are based on `React` and `Redux`.

#### Shared Folder
Following Hexagonal Architecture, the `shared` folder contains utilities, schemas, and other shared resources used across multiple views.

### Background Architecture

The `src\background` folder does not follow a specific architecture but is based on Events Architecture.

### Hierarchical Locking Order

To prevent deadlocks in the application, all threads must follow the "Hierarchical Locking Order" when acquiring resources:

1. **CLI**: Acquire any locks related to the command-line interface first.
2. **DATA**: Next, acquire locks related to data access or shared data structures.
3. **EVENT**: Finally, acquire locks related to hook or event management.

This order must be respected in all threads to avoid circular wait conditions and ensure safe concurrency.
16 changes: 16 additions & 0 deletions documentation/schemas/settings.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,15 @@
"type": "string"
}
},
"virtualDesktopStrategy": {
"description": "what virtual desktop implementation will be used, in case Native is not available we use Seelen",
"default": "Native",
"allOf": [
{
"$ref": "#/definitions/VirtualDesktopStrategy"
}
]
},
"windowManager": {
"description": "window manager config",
"default": {
Expand Down Expand Up @@ -1078,6 +1087,13 @@
"Bottom"
]
},
"VirtualDesktopStrategy": {
"type": "string",
"enum": [
"Native",
"Seelen"
]
},
"WindowManagerSettings": {
"type": "object",
"properties": {
Expand Down
141 changes: 89 additions & 52 deletions lib/src/state/settings.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,18 @@
/* In this file we use #[serde_alias(SnakeCase)] as backward compatibility from versions below v1.9.8 */

use std::collections::HashMap;

use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use serde_alias::serde_alias;

use crate::rect::Rect;

/* In this file we use #[serde_alias(SnakeCase)] as backward compatibility from versions below v1.9.8 */
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
pub enum VirtualDesktopStrategy {
Native,
Seelen,
}

#[serde_alias(SnakeCase)]
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
Expand All @@ -28,6 +36,8 @@ pub struct Settings {
pub dev_tools: bool,
/// language to use, if null the system locale is used
pub language: Option<String>,
/// what virtual desktop implementation will be used, in case Native is not available we use Seelen
pub virtual_desktop_strategy: VirtualDesktopStrategy,
}

impl Default for Settings {
Expand All @@ -42,6 +52,7 @@ impl Default for Settings {
ahk_variables: AhkVarList::default(),
dev_tools: false,
language: Some(Self::get_system_language()),
virtual_desktop_strategy: VirtualDesktopStrategy::Native,
}
}
}
Expand Down Expand Up @@ -277,6 +288,35 @@ impl Default for Monitor {

// ============== Ahk Variables ==============

#[macro_export]
macro_rules! define_struct_and_hashmap {
(
$($field:ident),*
) => {
#[serde_alias(SnakeCase)]
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
#[serde(default, rename_all = "camelCase")]
pub struct AhkVarList {
$(
pub $field: AhkVar,
)*
}

impl AhkVarList {
pub fn as_hash_map(&self) -> HashMap<String, AhkVar> {
let mut map = HashMap::new();
$(
map.insert(
stringify!($field).to_string(),
self.$field.clone()
);
)*
map
}
}
};
}

#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
pub struct AhkVar {
pub fancy: String,
Expand All @@ -292,57 +332,54 @@ impl AhkVar {
}
}

#[serde_alias(SnakeCase)]
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
#[serde(default, rename_all = "camelCase")]
pub struct AhkVarList {
pub reserve_top: AhkVar,
pub reserve_bottom: AhkVar,
pub reserve_left: AhkVar,
pub reserve_right: AhkVar,
pub reserve_float: AhkVar,
pub reserve_stack: AhkVar,
pub focus_top: AhkVar,
pub focus_bottom: AhkVar,
pub focus_left: AhkVar,
pub focus_right: AhkVar,
pub focus_latest: AhkVar,
pub increase_width: AhkVar,
pub decrease_width: AhkVar,
pub increase_height: AhkVar,
pub decrease_height: AhkVar,
pub restore_sizes: AhkVar,
pub switch_workspace_0: AhkVar,
pub switch_workspace_1: AhkVar,
pub switch_workspace_2: AhkVar,
pub switch_workspace_3: AhkVar,
pub switch_workspace_4: AhkVar,
pub switch_workspace_5: AhkVar,
pub switch_workspace_6: AhkVar,
pub switch_workspace_7: AhkVar,
pub switch_workspace_8: AhkVar,
pub switch_workspace_9: AhkVar,
pub move_to_workspace_0: AhkVar,
pub move_to_workspace_1: AhkVar,
pub move_to_workspace_2: AhkVar,
pub move_to_workspace_3: AhkVar,
pub move_to_workspace_4: AhkVar,
pub move_to_workspace_5: AhkVar,
pub move_to_workspace_6: AhkVar,
pub move_to_workspace_7: AhkVar,
pub move_to_workspace_8: AhkVar,
pub move_to_workspace_9: AhkVar,
pub send_to_workspace_0: AhkVar,
pub send_to_workspace_1: AhkVar,
pub send_to_workspace_2: AhkVar,
pub send_to_workspace_3: AhkVar,
pub send_to_workspace_4: AhkVar,
pub send_to_workspace_5: AhkVar,
pub send_to_workspace_6: AhkVar,
pub send_to_workspace_7: AhkVar,
pub send_to_workspace_8: AhkVar,
pub send_to_workspace_9: AhkVar,
}
define_struct_and_hashmap![
reserve_top,
reserve_bottom,
reserve_left,
reserve_right,
reserve_float,
reserve_stack,
focus_top,
focus_bottom,
focus_left,
focus_right,
focus_latest,
increase_width,
decrease_width,
increase_height,
decrease_height,
restore_sizes,
switch_workspace_0,
switch_workspace_1,
switch_workspace_2,
switch_workspace_3,
switch_workspace_4,
switch_workspace_5,
switch_workspace_6,
switch_workspace_7,
switch_workspace_8,
switch_workspace_9,
move_to_workspace_0,
move_to_workspace_1,
move_to_workspace_2,
move_to_workspace_3,
move_to_workspace_4,
move_to_workspace_5,
move_to_workspace_6,
move_to_workspace_7,
move_to_workspace_8,
move_to_workspace_9,
send_to_workspace_0,
send_to_workspace_1,
send_to_workspace_2,
send_to_workspace_3,
send_to_workspace_4,
send_to_workspace_5,
send_to_workspace_6,
send_to_workspace_7,
send_to_workspace_8,
send_to_workspace_9
];

impl Default for AhkVarList {
fn default() -> Self {
Expand Down
Loading

0 comments on commit e8eaed7

Please sign in to comment.