Skip to content

Commit

Permalink
enh(widget): add capabilities
Browse files Browse the repository at this point in the history
  • Loading branch information
eythaann committed Dec 5, 2024
1 parent d479d44 commit 45e0b9a
Show file tree
Hide file tree
Showing 14 changed files with 319 additions and 19 deletions.
14 changes: 14 additions & 0 deletions capabilities/general.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"$schema": "../gen/schemas/windows-schema.json",
"identifier": "general",
"description": "general permissions for all widgets",
"local": true,
"windows": [
"*"
],
"permissions": [
"log:default",
"core:event:default",
"core:webview:default"
]
}
65 changes: 65 additions & 0 deletions capabilities/general_window.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
{
"$schema": "../gen/schemas/windows-schema.json",
"identifier": "general-window",
"description": "core:window permissions for all widgets",
"local": true,
"windows": [
"*"
],
"permissions": [
"core:window:default",

"core:window:allow-show",
"core:window:allow-hide",

"core:window:deny-create",
"core:window:allow-destroy",

"core:window:allow-set-always-on-top",
"core:window:allow-set-always-on-bottom",
"core:window:allow-set-fullscreen",

"core:window:allow-center",
"core:window:allow-set-size",
"core:window:allow-set-size-constraints",
"core:window:allow-set-position",
"core:window:allow-set-min-size",
"core:window:allow-set-max-size",

"core:window:allow-set-resizable",
"core:window:allow-set-minimizable",
"core:window:allow-set-maximizable",
"core:window:allow-set-closable",

"core:window:allow-minimize",
"core:window:allow-unminimize",
"core:window:allow-maximize",
"core:window:allow-unmaximize",
"core:window:allow-toggle-maximize",
"core:window:allow-close",

"core:window:allow-set-title",
"core:window:allow-set-title-bar-style",
"core:window:allow-set-decorations",
"core:window:allow-set-shadow",
"core:window:allow-set-effects",
"core:window:allow-set-content-protected",
"core:window:allow-set-ignore-cursor-events",

"core:window:allow-set-skip-taskbar",
"core:window:allow-set-visible-on-all-workspaces",

"core:window:allow-set-icon",
"core:window:allow-set-progress-bar",
"core:window:allow-request-user-attention",

"core:window:allow-set-focus",
"core:window:allow-set-cursor-grab",
"core:window:allow-set-cursor-icon",
"core:window:allow-set-cursor-position",
"core:window:allow-set-cursor-visible",

"core:window:allow-start-dragging",
"core:window:allow-start-resize-dragging"
]
}
42 changes: 32 additions & 10 deletions scripts/build.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,14 @@ import { renderToStaticMarkup } from 'react-dom/server';
import yargs from 'yargs';
import { hideBin } from 'yargs/helpers';

async function ssrIcons() {
async function extractIconsIfNecessary() {
if (fs.existsSync('./dist/icons')) {
return;
}

console.time('Bundle Lazy Icons');
fs.mkdirSync('./dist/icons', { recursive: true });

const promises = [
import('react-icons/ai'),
import('react-icons/bi'),
Expand Down Expand Up @@ -48,6 +55,8 @@ async function ssrIcons() {
fs.writeFileSync(`./dist/icons/${name}.svg`, svg);
}
}

console.timeEnd('Bundle Lazy Icons');
}

async function main() {
Expand All @@ -63,20 +72,38 @@ async function main() {
.readdirSync('src/apps')
.filter((item) => item !== 'shared' && fs.statSync(path.join('src/apps', item)).isDirectory());

// remove previous build
appFolders.forEach((folder) => {
const filePath = path.join('dist', folder);
if (fs.existsSync(filePath)) {
fs.rmSync(filePath, { recursive: true, force: true });
}
});

const entryPoints = appFolders
.map((folder) => {
const vanilla = `./src/apps/${folder}/index.ts`;
const react = `./src/apps/${folder}/index.tsx`;
const svelte = `./src/apps/${folder}/index.svelte`;
if (fs.existsSync(vanilla)) {
return vanilla;
}
if (fs.existsSync(react)) {
return react;
}
if (fs.existsSync(svelte)) {
return svelte;
}
return '';
})
.filter((file) => !!file);

await esbuild.build({
entryPoints: appFolders
.map((folder) => `./src/apps/${folder}/index.tsx`)
.filter((file) => fs.existsSync(file)),
entryPoints: entryPoints,
bundle: true,
minify: isProdMode,
sourcemap: !isProdMode,
format: 'esm',
outdir: './dist',
jsx: 'automatic',
define: {
Expand All @@ -96,12 +123,7 @@ async function main() {
});
console.timeEnd('Build UI');

if (!fs.existsSync('./dist/icons')) {
console.time('Bundle Lazy Icons');
fs.mkdirSync('./dist/icons', { recursive: true });
await ssrIcons();
console.timeEnd('Bundle Lazy Icons');
}
await extractIconsIfNecessary();
}

main();
31 changes: 31 additions & 0 deletions src/apps/widget_loader/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { getCurrentWebviewWindow } from '@tauri-apps/api/webviewWindow';
import { WidgetList } from 'seelen-core';

import { wrapConsole } from '../shared/ConsoleWrapper';

wrapConsole();

const webview = getCurrentWebviewWindow();
const base64Label = webview.label;
const decodedLabel = atob(base64Label);

const list = await WidgetList.getAsync();
const widget = list.all().find((w) => w.id === decodedLabel);

if (widget) {
const { js, css, html } = widget;
if (html) {
document.body.innerHTML = html;
}
if (css) {
const style = document.createElement('style');
style.textContent = css;
document.head.appendChild(style);
}
if (js) {
const script = document.createElement('script');
script.type = 'module';
script.textContent = js;
document.head.appendChild(script);
}
}
13 changes: 13 additions & 0 deletions src/apps/widget_loader/public/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="icon" href="data:;base64,iVBORw0KGgo=" />
<link rel="stylesheet" href="./reset.css" />
<script src="./index.js" type="module" defer></script>
</head>
<body>
<!-- widget will fill this -->
</body>
</html>
116 changes: 116 additions & 0 deletions src/apps/widget_loader/public/reset.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
@layer reset {
:root {
font-size: 100%;
--main-typo: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu,
Cantarell, "Open Sans", "Helvetica Neue", sans-serif;
--primary-color: var(--color-gray-900);
--secondary-color: var(--color-gray-50);
}

*,
*:after,
*:before {
margin: 0;
padding: 0;
border: 0;
outline: none;
box-sizing: border-box;
vertical-align: baseline;
-webkit-user-select: none;
user-select: none;
}

img,
image,
picture,
video,
iframe,
figure {
max-width: 100%;
width: 100%;
display: block;
}

a {
display: block;
}

p a {
display: inline;
}

li {
list-style-type: none;
}

html {
scroll-behavior: smooth;
}

h1,
h2,
h3,
h4,
h5,
h6,
p,
span,
a,
strong,
blockquote,
i,
b,
em,
pre {
font-size: 1em;
font-weight: inherit;
font-style: inherit;
text-decoration: none;
color: inherit;
}

form,
input,
textarea,
select,
button,
label {
font-family: inherit;
font-size: inherit;
hyphens: auto;
background-color: transparent;
display: block;
color: inherit;
}

table,
tr,
td {
border-collapse: collapse;
border-spacing: 0;
}

svg {
width: 100%;
display: block;
}

body {
font-size: 1em;
line-height: 1.4em;
font-family: var(--main-typo);
color: var(--primary-color);
background-color: var(--secondary-color);
hyphens: auto;
font-smooth: always;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}

hr {
border: 1px solid;
margin: 1em 0;
opacity: 0.8;
color: var(--color-gray-200);
}
}
16 changes: 16 additions & 0 deletions src/background/instance.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use std::collections::HashMap;

use getset::{Getters, MutGetters};

use crate::{
Expand All @@ -7,6 +9,7 @@ use crate::{
seelen_weg::SeelenWeg,
seelen_wm_v2::instance::WindowManagerV2,
state::application::FullState,
widget_loader::WidgetInstance,
windows_api::{monitor::Monitor, WindowsApi},
};

Expand All @@ -21,6 +24,8 @@ pub struct SeelenInstanceContainer {
toolbar: Option<FancyToolbar>,
weg: Option<SeelenWeg>,
wm: Option<WindowManagerV2>,
/// third party widgets
widgets: HashMap<String, WidgetInstance>,
}

unsafe impl Send for SeelenInstanceContainer {}
Expand All @@ -37,6 +42,7 @@ impl SeelenInstanceContainer {
toolbar: None,
weg: None,
wm: None,
widgets: HashMap::new(),
};
instance.load_settings(settings)?;
instance.ensure_positions()?;
Expand Down Expand Up @@ -101,6 +107,16 @@ impl SeelenInstanceContainer {
} else {
self.wm = None;
}

for (id, widget) in &settings.widgets {
// Todo: filter by widget settings (enabled state)
if self.widgets.contains_key(id) || widget.html.is_none() {
continue;
}
self.widgets
.insert(id.clone(), WidgetInstance::load(widget.clone())?);
}

Ok(())
}

Expand Down
1 change: 1 addition & 0 deletions src/background/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ mod state;
mod system;
mod tray;
mod utils;
mod widget_loader;
mod windows_api;
mod winevent;

Expand Down
Loading

0 comments on commit 45e0b9a

Please sign in to comment.