Skip to content
Open
Show file tree
Hide file tree
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
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,8 @@ Note: The application is **NOT** invisible to:
- No additional permissions needed
- On Linux:
- May require `xhost` access depending on your distribution
- If using wayland: install `grim`
- If using gnome: install `gnome-screenshot` (if not already installed)

## Running the Application

Expand Down
75 changes: 73 additions & 2 deletions electron/ScreenshotHelper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -148,11 +148,17 @@ export class ScreenshotHelper {
private async captureScreenshot(): Promise<Buffer> {
try {
console.log("Starting screenshot capture...");


// Check if running on Wayland
if (process.env.XDG_SESSION_TYPE === 'wayland') {
console.log("Detected Wayland session");
return await this.captureWaylandScreenshot();
}

// For Windows, try multiple methods
if (process.platform === 'win32') {
return await this.captureWindowsScreenshot();
}
}

// For macOS and Linux, use buffer directly
console.log("Taking screenshot on non-Windows platform");
Expand All @@ -165,6 +171,71 @@ export class ScreenshotHelper {
}
}

/**
* Wayland screenshot capture
*/
private async captureWaylandScreenshot(): Promise<Buffer> {
try {
const currentDesktop = process.env.XDG_CURRENT_DESKTOP;
if (currentDesktop?.toLowerCase().includes('gnome')) {
console.log("Detected GNOME on Wayland, using gnome-screenshot instead.");
return await this.captureGnomeScreenshot();
}

console.log("Taking screenshot on Wayland with grim");
const tempFile = path.join(this.tempDir, `temp-${uuidv4()}.png`);
await execFileAsync('grim', ['-g', '0,0 1920x1080', tempFile]);

if (!fs.existsSync(tempFile)) {
throw new Error("Screenshot file not created by grim");
}

const buffer = await fs.promises.readFile(tempFile);
console.log(`Screenshot captured successfully, size: ${buffer.length} bytes`);

try {
await fs.promises.unlink(tempFile);
} catch (cleanupErr) {
console.warn("Failed to clean up temp file:", cleanupErr);
}

return buffer;
} catch (error) {
console.error("Error capturing Wayland screenshot:", error);
throw new Error(`Failed to capture Wayland screenshot: ${error.message}`);
}
}

/**
* GNOME Wayland screenshot capture using gnome-screenshot
*/
private async captureGnomeScreenshot(): Promise<Buffer> {
try {
console.log("Taking screenshot on GNOME with gnome-screenshot");

const tempFile = path.join(this.tempDir, `gnome-temp-${uuidv4()}.png`);
await execFileAsync('gnome-screenshot', ['-f', tempFile]);

if (!fs.existsSync(tempFile)) {
throw new Error("Screenshot file not created by gnome-screenshot");
}

const buffer = await fs.promises.readFile(tempFile);
console.log(`Screenshot captured successfully, size: ${buffer.length} bytes`);

try {
await fs.promises.unlink(tempFile);
} catch (cleanupErr) {
console.warn("Failed to clean up temp file:", cleanupErr);
}

return buffer;
} catch (error) {
console.error("Error capturing GNOME screenshot:", error);
throw new Error(`Failed to capture GNOME screenshot: ${error.message}`);
}
}

/**
* Windows-specific screenshot capture with multiple fallback mechanisms
*/
Expand Down
Loading