Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multi-monitor support #11

Merged
merged 18 commits into from
Jan 17, 2022
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -66,6 +66,8 @@
"typescript": "^4.3.5"
},
"dependencies": {
"fp-ts": "^2.11.7",
"io-ts": "^2.2.16",
"js-yaml": "^4.1.0",
"node-gtk": "^0.9.0",
"winston": "^3.3.3",
2 changes: 2 additions & 0 deletions themes/dracula/index.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
primary_html: "index.html"
secondary_html: "secondary.html"
23 changes: 20 additions & 3 deletions themes/dracula/js/backgrounds.js
Original file line number Diff line number Diff line change
@@ -5,12 +5,22 @@ class Backgrounds {
"assets/dracula.png",
"assets/window-blurred.png",
];
this._sidebar = document.querySelector("#sidebar");
this._backgroundsList = document.querySelector("#background-selector");
this._background = document.querySelector("#background");
this._backgroundImages = null;
this._backgroundImagesDir = null;
this._backgroundPath = "";

/**
* Background change requests are handled via broadcast events so that all
* windows correctly update.
*/
window.addEventListener("NodyBroadcastEvent", (ev) => {
if (ev.data.type == "change-background") {
this._backgroundPath = ev.data.path;
this._updateBackgroundImages();
}
});
}

_createImage(path) {
@@ -57,8 +67,15 @@ class Backgrounds {
const path = this._backgroundImages[i];
let button = this._createImage(path);
button.addEventListener("click", () => {
this._backgroundPath = path;
this._updateBackgroundImages();
if (window.nody_greeter) {
nody_greeter.broadcast({
type: "change-background",
path,
});
} else {
this._backgroundPath = path;
this._updateBackgroundImages();
}
});
this._backgroundsList.appendChild(button);
}
8 changes: 4 additions & 4 deletions themes/dracula/js/index.js
Original file line number Diff line number Diff line change
@@ -46,11 +46,11 @@ async function initGreeter() {
battery = new Battery();

brightness = new Brightness();
}

if (window._ready_event === undefined) {
_ready_event = new Event("GreeterReady");
window.dispatchEvent(_ready_event);
if (window.nody_greeter && !window.nody_greeter.window_metadata.is_primary) {
// Hide login elements on non-primary screen
document.querySelector("#screen").classList.add("hide");
}
}

window.addEventListener("GreeterReady", initGreeter);
31 changes: 31 additions & 0 deletions themes/dracula/js/secondary.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
async function wait(ms) {
return new Promise((resolve) => {
setTimeout(() => {
resolve();
}, ms);
});
}

async function _authentication_done() {
await wait(1000);
var body = document.querySelector("body");
body.style.opacity = 0;
}

function authentication_done() {
if (lightdm.is_authenticated) _authentication_done();
}

function initGreeter() {
lightdm.authentication_complete?.connect(() => authentication_done());

backgrounds = new Backgrounds();
backgrounds._init();
}

if (window._ready_event === undefined) {
_ready_event = new Event("GreeterReady");
window.dispatchEvent(_ready_event);
}

window.addEventListener("GreeterReady", initGreeter);
32 changes: 32 additions & 0 deletions themes/dracula/secondary.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta
name="viewport"
content="width=device-width, viewport-fit=cover, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no"
/>

<link rel="stylesheet" href="css/style.css" class="style" />
<link
rel="stylesheet"
href="../../_vendor/material-icons/css/materialdesignicons.min.css"
onerror="this.href='../_vendor/material-icons/css/materialdesignicons.min.css'"
class="style"
/>

<!--<script src="../_vendor/js/mock.js"></script>-->

<title>Dracula theme</title>
</head>
<body>
<div id="background">
<div id="bg-cover"></div>
</div>

<div id="background-selector" style="display: none"></div>

<script src="js/backgrounds.js"></script>
<script src="js/secondary.js"></script>
</body>
</html>
2 changes: 2 additions & 0 deletions themes/gruvbox/index.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
primary_html: "index.html"
secondary_html: "secondary.html"
10 changes: 5 additions & 5 deletions themes/gruvbox/js/index.js
Original file line number Diff line number Diff line change
@@ -48,13 +48,13 @@ async function initGreeter() {
if (lock) {
document.querySelector("#lock-label").classList.remove("hide");
}

if (window.nody_greeter && !window.nody_greeter.window_metadata.is_primary) {
// Hide login elements on non-primary screen
document.querySelector("#screen").classList.add("hide");
}
}

const notGreeter = false;

if (window._ready_event === undefined) {
_ready_event = new Event("GreeterReady");
window.dispatchEvent(_ready_event);
}

window.addEventListener("GreeterReady", initGreeter);
28 changes: 28 additions & 0 deletions themes/gruvbox/js/secondary.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
async function wait(ms) {
return new Promise((resolve) => {
setTimeout(() => {
resolve();
}, ms);
});
}

async function _authentication_done() {
await wait(500);
var body = document.querySelector("body");
body.style.opacity = 0;
}

function authentication_done() {
if (lightdm.is_authenticated) _authentication_done();
}

function initGreeter() {
lightdm.authentication_complete?.connect(() => authentication_done());
}

if (window._ready_event === undefined) {
_ready_event = new Event("GreeterReady");
window.dispatchEvent(_ready_event);
}

window.addEventListener("GreeterReady", initGreeter);
27 changes: 27 additions & 0 deletions themes/gruvbox/secondary.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta
name="viewport"
content="width=device-width, viewport-fit=cover, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no"
/>

<link rel="stylesheet" href="css/style.css" class="style" />
<link
rel="stylesheet"
href="../../_vendor/material-icons/css/materialdesignicons.min.css"
onerror="this.href='../_vendor/material-icons/css/materialdesignicons.min.css'"
class="style"
/>

<!--<script src="../_vendor/js/mock.js"></script>-->

<title>Gruvbox theme</title>
</head>
<body>
<div id="background"></div>

<script src="js/secondary.js"></script>
</body>
</html>
42 changes: 40 additions & 2 deletions ts/bridge/bridge.ts
Original file line number Diff line number Diff line change
@@ -30,6 +30,7 @@ import {
LightDMUser,
} from "../ldm_interfaces";
import { logger } from "../logger";
import { CONSTS } from "../consts";

export class Greeter {
_config: web_greeter_config;
@@ -53,7 +54,7 @@ export class Greeter {
} catch (err) {
logger.error(err);
browser.whenReady().then(() => {
dialog.showMessageBoxSync(browser.win, {
dialog.showMessageBoxSync(browser.primary_window, {
message:
"Detected a problem that could interfere with the system login process", // Yeah, that problematic message
detail: `LightDM: ${err}\nYou can continue without major problems, but you won't be able to log in`,
@@ -103,7 +104,13 @@ export class Greeter {

_emit_signal(signal: string, ...args: unknown[]): void {
//console.log("SIGNAL EMITTED", signal, args)
browser.win.webContents.send("LightDMSignal", signal, ...args);
for (const win of browser.windows) {
win.window.webContents.send(
CONSTS.channel.lightdm_signal,
signal,
...args
);
}
}

/**
@@ -727,6 +734,37 @@ ipcMain.on("lightdm", (ev, ...args) => {
handler(globalThis.lightdm, ev, ...args);
});

ipcMain.on(CONSTS.channel.window_metadata, (ev) => {
/**
* A request on this channel simply means that a browser window is ready to
* receive metadata (i.e. on initial load or a refresh)
*/
for (const window of browser.windows) {
if (window.window.webContents === ev.sender) {
window.window.webContents.send(
CONSTS.channel.window_metadata,
window.meta
);
}
}
});

ipcMain.on(CONSTS.channel.window_broadcast, (ev, data: unknown) => {
const sendingWindow = browser.windows.find(
(w) => w.window.webContents === ev.sender
);
if (!sendingWindow) {
throw new Error(`Unable to find window for event ${ev}`);
}
for (const window of browser.windows) {
window.window.webContents.send(
CONSTS.channel.window_broadcast,
sendingWindow.meta,
data
);
}
});

browser.whenReady().then(() => {
new Greeter(nody_greeter.config);
new GreeterConfig(nody_greeter.config);
Loading