├── src-tauri
├── xrandr
│ ├── .gitignore
│ ├── .cargo_vcs_info.json
│ ├── README.md
│ ├── Cargo.toml.orig
│ ├── Cargo.toml
│ └── src
│ │ ├── monitor.rs
│ │ ├── screensize.rs
│ │ ├── mode.rs
│ │ ├── output
│ │ └── mod.rs
│ │ ├── screen_resources.rs
│ │ ├── crtc.rs
│ │ └── lib.rs
├── build.rs
├── icons
│ ├── 32x32.png
│ ├── icon.icns
│ ├── icon.ico
│ ├── icon.png
│ ├── 128x128.png
│ ├── 128x128@2.png
│ ├── 128x128@2x.png
│ ├── StoreLogo.png
│ ├── Square30x30Logo.png
│ ├── Square44x44Logo.png
│ ├── Square71x71Logo.png
│ ├── Square89x89Logo.png
│ ├── Square107x107Logo.png
│ ├── Square142x142Logo.png
│ ├── Square150x150Logo.png
│ ├── Square284x284Logo.png
│ ├── Square310x310Logo.png
│ ├── ios
│ │ ├── AppIcon-512@2x.png
│ │ ├── AppIcon-20x20@1x.png
│ │ ├── AppIcon-20x20@2x.png
│ │ ├── AppIcon-20x20@3x.png
│ │ ├── AppIcon-29x29@1x.png
│ │ ├── AppIcon-29x29@2x.png
│ │ ├── AppIcon-29x29@3x.png
│ │ ├── AppIcon-40x40@1x.png
│ │ ├── AppIcon-40x40@2x.png
│ │ ├── AppIcon-40x40@3x.png
│ │ ├── AppIcon-60x60@2x.png
│ │ ├── AppIcon-60x60@3x.png
│ │ ├── AppIcon-76x76@1x.png
│ │ ├── AppIcon-76x76@2x.png
│ │ ├── AppIcon-20x20@2x-1.png
│ │ ├── AppIcon-29x29@2x-1.png
│ │ ├── AppIcon-40x40@2x-1.png
│ │ └── AppIcon-83.5x83.5@2x.png
│ └── android
│ │ ├── mipmap-hdpi
│ │ ├── ic_launcher.png
│ │ ├── ic_launcher_round.png
│ │ └── ic_launcher_foreground.png
│ │ ├── mipmap-mdpi
│ │ ├── ic_launcher.png
│ │ ├── ic_launcher_round.png
│ │ └── ic_launcher_foreground.png
│ │ ├── mipmap-xhdpi
│ │ ├── ic_launcher.png
│ │ ├── ic_launcher_round.png
│ │ └── ic_launcher_foreground.png
│ │ ├── mipmap-xxhdpi
│ │ ├── ic_launcher.png
│ │ ├── ic_launcher_round.png
│ │ └── ic_launcher_foreground.png
│ │ └── mipmap-xxxhdpi
│ │ ├── ic_launcher.png
│ │ ├── ic_launcher_round.png
│ │ └── ic_launcher_foreground.png
├── .gitignore
├── src
│ ├── main.rs
│ └── lib.rs
├── capabilities
│ └── default.json
├── Cargo.toml
└── tauri.conf.json
├── src
├── vite-env.d.ts
├── main.tsx
├── components
│ ├── LoadingScreen.tsx
│ ├── Popups
│ │ ├── SimplePopUp.tsx
│ │ ├── SingleErrorPopUp.tsx
│ │ ├── SingleErrorPopUp.css
│ │ ├── MassApplyUndoPopup.css
│ │ ├── SimplePopUp.css
│ │ ├── ApplySettingsPopup.css
│ │ ├── MassApplyUndoPopup.tsx
│ │ └── ApplySettingsPopup.tsx
│ ├── FreeHandPosition.css
│ ├── Loading.css
│ ├── Presets.css
│ ├── Loaded.css
│ ├── FocusedMonitorSettings.css
│ ├── Presets.tsx
│ ├── LoadedScreen.tsx
│ ├── FocusedMonitorSettings.tsx
│ └── FreeHandPosition.tsx
├── App.css
├── globalValues.tsx
└── App.tsx
├── .vscode
└── extensions.json
├── .prettierrc
├── tsconfig.node.json
├── .gitignore
├── index.html
├── tsconfig.json
├── package.json
├── vite.config.ts
└── README.md
/src-tauri/xrandr/.gitignore:
--------------------------------------------------------------------------------
1 | /target
2 | Cargo.lock
3 |
--------------------------------------------------------------------------------
/src/vite-env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
--------------------------------------------------------------------------------
/src-tauri/build.rs:
--------------------------------------------------------------------------------
1 | fn main() {
2 | tauri_build::build()
3 | }
4 |
--------------------------------------------------------------------------------
/.vscode/extensions.json:
--------------------------------------------------------------------------------
1 | {
2 | "recommendations": ["tauri-apps.tauri-vscode", "rust-lang.rust-analyzer"]
3 | }
4 |
--------------------------------------------------------------------------------
/src-tauri/icons/32x32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bossadapt/Display-Settings-Plus/HEAD/src-tauri/icons/32x32.png
--------------------------------------------------------------------------------
/src-tauri/icons/icon.icns:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bossadapt/Display-Settings-Plus/HEAD/src-tauri/icons/icon.icns
--------------------------------------------------------------------------------
/src-tauri/icons/icon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bossadapt/Display-Settings-Plus/HEAD/src-tauri/icons/icon.ico
--------------------------------------------------------------------------------
/src-tauri/icons/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bossadapt/Display-Settings-Plus/HEAD/src-tauri/icons/icon.png
--------------------------------------------------------------------------------
/src-tauri/icons/128x128.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bossadapt/Display-Settings-Plus/HEAD/src-tauri/icons/128x128.png
--------------------------------------------------------------------------------
/src-tauri/icons/128x128@2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bossadapt/Display-Settings-Plus/HEAD/src-tauri/icons/128x128@2.png
--------------------------------------------------------------------------------
/src-tauri/icons/128x128@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bossadapt/Display-Settings-Plus/HEAD/src-tauri/icons/128x128@2x.png
--------------------------------------------------------------------------------
/src-tauri/icons/StoreLogo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bossadapt/Display-Settings-Plus/HEAD/src-tauri/icons/StoreLogo.png
--------------------------------------------------------------------------------
/src-tauri/icons/Square30x30Logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bossadapt/Display-Settings-Plus/HEAD/src-tauri/icons/Square30x30Logo.png
--------------------------------------------------------------------------------
/src-tauri/icons/Square44x44Logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bossadapt/Display-Settings-Plus/HEAD/src-tauri/icons/Square44x44Logo.png
--------------------------------------------------------------------------------
/src-tauri/icons/Square71x71Logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bossadapt/Display-Settings-Plus/HEAD/src-tauri/icons/Square71x71Logo.png
--------------------------------------------------------------------------------
/src-tauri/icons/Square89x89Logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bossadapt/Display-Settings-Plus/HEAD/src-tauri/icons/Square89x89Logo.png
--------------------------------------------------------------------------------
/src-tauri/icons/Square107x107Logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bossadapt/Display-Settings-Plus/HEAD/src-tauri/icons/Square107x107Logo.png
--------------------------------------------------------------------------------
/src-tauri/icons/Square142x142Logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bossadapt/Display-Settings-Plus/HEAD/src-tauri/icons/Square142x142Logo.png
--------------------------------------------------------------------------------
/src-tauri/icons/Square150x150Logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bossadapt/Display-Settings-Plus/HEAD/src-tauri/icons/Square150x150Logo.png
--------------------------------------------------------------------------------
/src-tauri/icons/Square284x284Logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bossadapt/Display-Settings-Plus/HEAD/src-tauri/icons/Square284x284Logo.png
--------------------------------------------------------------------------------
/src-tauri/icons/Square310x310Logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bossadapt/Display-Settings-Plus/HEAD/src-tauri/icons/Square310x310Logo.png
--------------------------------------------------------------------------------
/src-tauri/icons/ios/AppIcon-512@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bossadapt/Display-Settings-Plus/HEAD/src-tauri/icons/ios/AppIcon-512@2x.png
--------------------------------------------------------------------------------
/src-tauri/icons/ios/AppIcon-20x20@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bossadapt/Display-Settings-Plus/HEAD/src-tauri/icons/ios/AppIcon-20x20@1x.png
--------------------------------------------------------------------------------
/src-tauri/icons/ios/AppIcon-20x20@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bossadapt/Display-Settings-Plus/HEAD/src-tauri/icons/ios/AppIcon-20x20@2x.png
--------------------------------------------------------------------------------
/src-tauri/icons/ios/AppIcon-20x20@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bossadapt/Display-Settings-Plus/HEAD/src-tauri/icons/ios/AppIcon-20x20@3x.png
--------------------------------------------------------------------------------
/src-tauri/icons/ios/AppIcon-29x29@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bossadapt/Display-Settings-Plus/HEAD/src-tauri/icons/ios/AppIcon-29x29@1x.png
--------------------------------------------------------------------------------
/src-tauri/icons/ios/AppIcon-29x29@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bossadapt/Display-Settings-Plus/HEAD/src-tauri/icons/ios/AppIcon-29x29@2x.png
--------------------------------------------------------------------------------
/src-tauri/icons/ios/AppIcon-29x29@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bossadapt/Display-Settings-Plus/HEAD/src-tauri/icons/ios/AppIcon-29x29@3x.png
--------------------------------------------------------------------------------
/src-tauri/icons/ios/AppIcon-40x40@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bossadapt/Display-Settings-Plus/HEAD/src-tauri/icons/ios/AppIcon-40x40@1x.png
--------------------------------------------------------------------------------
/src-tauri/icons/ios/AppIcon-40x40@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bossadapt/Display-Settings-Plus/HEAD/src-tauri/icons/ios/AppIcon-40x40@2x.png
--------------------------------------------------------------------------------
/src-tauri/icons/ios/AppIcon-40x40@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bossadapt/Display-Settings-Plus/HEAD/src-tauri/icons/ios/AppIcon-40x40@3x.png
--------------------------------------------------------------------------------
/src-tauri/icons/ios/AppIcon-60x60@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bossadapt/Display-Settings-Plus/HEAD/src-tauri/icons/ios/AppIcon-60x60@2x.png
--------------------------------------------------------------------------------
/src-tauri/icons/ios/AppIcon-60x60@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bossadapt/Display-Settings-Plus/HEAD/src-tauri/icons/ios/AppIcon-60x60@3x.png
--------------------------------------------------------------------------------
/src-tauri/icons/ios/AppIcon-76x76@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bossadapt/Display-Settings-Plus/HEAD/src-tauri/icons/ios/AppIcon-76x76@1x.png
--------------------------------------------------------------------------------
/src-tauri/icons/ios/AppIcon-76x76@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bossadapt/Display-Settings-Plus/HEAD/src-tauri/icons/ios/AppIcon-76x76@2x.png
--------------------------------------------------------------------------------
/src-tauri/icons/ios/AppIcon-20x20@2x-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bossadapt/Display-Settings-Plus/HEAD/src-tauri/icons/ios/AppIcon-20x20@2x-1.png
--------------------------------------------------------------------------------
/src-tauri/icons/ios/AppIcon-29x29@2x-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bossadapt/Display-Settings-Plus/HEAD/src-tauri/icons/ios/AppIcon-29x29@2x-1.png
--------------------------------------------------------------------------------
/src-tauri/icons/ios/AppIcon-40x40@2x-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bossadapt/Display-Settings-Plus/HEAD/src-tauri/icons/ios/AppIcon-40x40@2x-1.png
--------------------------------------------------------------------------------
/src-tauri/xrandr/.cargo_vcs_info.json:
--------------------------------------------------------------------------------
1 | {
2 | "git": {
3 | "sha1": "cc06409aeace2076a73e0839ffce18bfb0809f8f"
4 | },
5 | "path_in_vcs": ""
6 | }
--------------------------------------------------------------------------------
/src-tauri/icons/ios/AppIcon-83.5x83.5@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bossadapt/Display-Settings-Plus/HEAD/src-tauri/icons/ios/AppIcon-83.5x83.5@2x.png
--------------------------------------------------------------------------------
/.prettierrc:
--------------------------------------------------------------------------------
1 |
2 | {
3 | "jsxSingleQuote": true,
4 | "printWidth": 100,
5 | "singleQuote": true,
6 | "trailingComma": "es5",
7 | "arrowParens": "avoid"
8 |
9 | }
--------------------------------------------------------------------------------
/src-tauri/icons/android/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bossadapt/Display-Settings-Plus/HEAD/src-tauri/icons/android/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/src-tauri/icons/android/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bossadapt/Display-Settings-Plus/HEAD/src-tauri/icons/android/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/src-tauri/icons/android/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bossadapt/Display-Settings-Plus/HEAD/src-tauri/icons/android/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/src-tauri/icons/android/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bossadapt/Display-Settings-Plus/HEAD/src-tauri/icons/android/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/src-tauri/icons/android/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bossadapt/Display-Settings-Plus/HEAD/src-tauri/icons/android/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/src-tauri/icons/android/mipmap-hdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bossadapt/Display-Settings-Plus/HEAD/src-tauri/icons/android/mipmap-hdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/src-tauri/icons/android/mipmap-mdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bossadapt/Display-Settings-Plus/HEAD/src-tauri/icons/android/mipmap-mdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/src-tauri/icons/android/mipmap-xhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bossadapt/Display-Settings-Plus/HEAD/src-tauri/icons/android/mipmap-xhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/src-tauri/icons/android/mipmap-xxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bossadapt/Display-Settings-Plus/HEAD/src-tauri/icons/android/mipmap-xxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/src-tauri/icons/android/mipmap-xxxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bossadapt/Display-Settings-Plus/HEAD/src-tauri/icons/android/mipmap-xxxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/src-tauri/icons/android/mipmap-hdpi/ic_launcher_foreground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bossadapt/Display-Settings-Plus/HEAD/src-tauri/icons/android/mipmap-hdpi/ic_launcher_foreground.png
--------------------------------------------------------------------------------
/src-tauri/icons/android/mipmap-mdpi/ic_launcher_foreground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bossadapt/Display-Settings-Plus/HEAD/src-tauri/icons/android/mipmap-mdpi/ic_launcher_foreground.png
--------------------------------------------------------------------------------
/src-tauri/icons/android/mipmap-xhdpi/ic_launcher_foreground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bossadapt/Display-Settings-Plus/HEAD/src-tauri/icons/android/mipmap-xhdpi/ic_launcher_foreground.png
--------------------------------------------------------------------------------
/src-tauri/icons/android/mipmap-xxhdpi/ic_launcher_foreground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bossadapt/Display-Settings-Plus/HEAD/src-tauri/icons/android/mipmap-xxhdpi/ic_launcher_foreground.png
--------------------------------------------------------------------------------
/src-tauri/icons/android/mipmap-xxxhdpi/ic_launcher_foreground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bossadapt/Display-Settings-Plus/HEAD/src-tauri/icons/android/mipmap-xxxhdpi/ic_launcher_foreground.png
--------------------------------------------------------------------------------
/src-tauri/.gitignore:
--------------------------------------------------------------------------------
1 | # Generated by Cargo
2 | # will have compiled files and executables
3 | /target/
4 |
5 | # Generated by Tauri
6 | # will have schema files for capabilities auto-completion
7 | /gen/schemas
8 | ./Preset*
--------------------------------------------------------------------------------
/src-tauri/src/main.rs:
--------------------------------------------------------------------------------
1 | // Prevents additional console window on Windows in release, DO NOT REMOVE!!
2 | #![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
3 |
4 | fn main() {
5 | display_settings_plus_lib::run()
6 | }
7 |
--------------------------------------------------------------------------------
/tsconfig.node.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "composite": true,
4 | "skipLibCheck": true,
5 | "module": "ESNext",
6 | "moduleResolution": "bundler",
7 | "allowSyntheticDefaultImports": true
8 | },
9 | "include": ["vite.config.ts"]
10 | }
11 |
--------------------------------------------------------------------------------
/src/main.tsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import ReactDOM from "react-dom/client";
3 | import App from "./App";
4 |
5 | ReactDOM.createRoot(document.getElementById("root") as HTMLElement).render(
6 |
7 |
8 | ,
9 | );
10 |
--------------------------------------------------------------------------------
/src-tauri/capabilities/default.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "../gen/schemas/desktop-schema.json",
3 | "identifier": "default",
4 | "description": "Capability for the main window",
5 | "windows": ["main"],
6 | "permissions": [
7 | "core:default",
8 | "opener:default"
9 | ]
10 | }
11 |
--------------------------------------------------------------------------------
/src/components/LoadingScreen.tsx:
--------------------------------------------------------------------------------
1 | // yoinked from https://codepen.io/AlbertFeynman/pen/zLEegX
2 | import './Loading.css';
3 | function LoadingScreen() {
4 | return (
5 |
6 |
LOADING
7 |
8 | );
9 | }
10 | export default LoadingScreen;
--------------------------------------------------------------------------------
/src/App.css:
--------------------------------------------------------------------------------
1 |
2 | body{
3 | margin: 0%;
4 | }
5 | @media (prefers-color-scheme: dark) {
6 | :root {
7 | color: #f6f6f6;
8 | }
9 |
10 | a:hover {
11 | color: #24c8db;
12 | }
13 |
14 | input,
15 | button {
16 | color: #ffffff;
17 | background-color: black;
18 | }
19 | button:active {
20 | background-color: #0f0f0f69;
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 | pnpm-debug.log*
8 | lerna-debug.log*
9 |
10 | node_modules
11 | dist
12 | dist-ssr
13 | *.local
14 |
15 | # Editor directories and files
16 | .vscode/*
17 | !.vscode/extensions.json
18 | .idea
19 | .DS_Store
20 | *.suo
21 | *.ntvs*
22 | *.njsproj
23 | *.sln
24 | *.sw?
25 |
26 | src-tauri/Preset*
27 |
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Tauri + React + Typescript
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/src-tauri/xrandr/README.md:
--------------------------------------------------------------------------------
1 | # xrandr
2 |
3 | 
4 | 
5 |
6 | This crate aims to provide safe bindings to libxrandr, a library for
7 | communicating with monitors and displays using X11 on Linux.
8 |
9 | This crate currently supports reading most monitor properties.
10 |
11 | For the equivalent on Windows see [monitor-control-win][monitor-control-win-crate].
12 |
13 | [monitor-control-win-crate]: https://crates.io/crates/monitor-control-win
14 |
--------------------------------------------------------------------------------
/src/components/Popups/SimplePopUp.tsx:
--------------------------------------------------------------------------------
1 | import "./SimplePopUp.css";
2 |
3 | interface SimplePopUpProps {
4 | showSimplePopUp: boolean,
5 | reasonForPopUp: string
6 | }
7 | export const SimplePopUp: React.FC = ({ showSimplePopUp, reasonForPopUp }) => {
8 | return (
9 |
10 |
11 |
12 |
{reasonForPopUp}
13 |
14 |
15 | );
16 | };
17 | export default SimplePopUp;
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES2020",
4 | "useDefineForClassFields": true,
5 | "lib": ["ES2020", "DOM", "DOM.Iterable"],
6 | "module": "ESNext",
7 | "skipLibCheck": true,
8 |
9 | /* Bundler mode */
10 | "moduleResolution": "bundler",
11 | "allowImportingTsExtensions": true,
12 | "resolveJsonModule": true,
13 | "isolatedModules": true,
14 | "noEmit": true,
15 | "jsx": "react-jsx",
16 |
17 | /* Linting */
18 | "strict": true,
19 | "noUnusedLocals": true,
20 | "noUnusedParameters": true,
21 | "noFallthroughCasesInSwitch": true
22 | },
23 | "include": ["src"],
24 | "references": [{ "path": "./tsconfig.node.json" }]
25 | }
26 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "display-settings-plus",
3 | "private": true,
4 | "version": "0.1.0",
5 | "type": "module",
6 | "scripts": {
7 | "dev": "vite",
8 | "build": "tsc && vite build",
9 | "preview": "vite preview",
10 | "tauri": "tauri"
11 | },
12 | "dependencies": {
13 | "@tauri-apps/api": "^2",
14 | "@tauri-apps/plugin-opener": "^2",
15 | "lodash": "^4.17.21",
16 | "pixi.js": "^8.8.0",
17 | "react": "^18.3.1",
18 | "react-dom": "^18.3.1",
19 | "react-select": "^5.9.0"
20 | },
21 | "devDependencies": {
22 | "@tauri-apps/cli": "^2",
23 | "@types/lodash": "^4.14.195",
24 | "@types/react": "^18.3.1",
25 | "@types/react-dom": "^18.3.1",
26 | "@vitejs/plugin-react": "^4.3.4",
27 | "typescript": "~5.6.2",
28 | "vite": "^6.0.3"
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/src-tauri/xrandr/Cargo.toml.orig:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "xrandr"
3 | version = "0.2.0"
4 | authors = [ "Rintse", "Daniel Franklin " ]
5 | edition = "2021"
6 | description = "Safe rust bindings to (some parts of) xrandr"
7 | license = "MIT"
8 | repository = "https://github.com/danielzfranklin/xrandr-rs"
9 | keywords = ["xrandr", "libxrandr", "libxrandr2", "bindings", "linux"]
10 | categories = ["os::linux-apis", "api-bindings"]
11 |
12 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
13 |
14 | [dependencies]
15 | thiserror = "1.0.24"
16 | x11 = { version = "2.18.2", features = ["xlib", "xrandr"] }
17 | indexmap = "1.6.2"
18 | serde = {version = "1.0.133", features=["derive"], optional=true}
19 | time = "0.3.20"
20 | itertools = "0.10.5"
21 | libc = "0.2.146"
22 |
23 | [features]
24 | serialize = ["serde", "indexmap/serde-1"]
25 |
--------------------------------------------------------------------------------
/vite.config.ts:
--------------------------------------------------------------------------------
1 | import { defineConfig } from "vite";
2 | import react from "@vitejs/plugin-react";
3 |
4 | // @ts-expect-error process is a nodejs global
5 | const host = process.env.TAURI_DEV_HOST;
6 |
7 | // https://vitejs.dev/config/
8 | export default defineConfig(async () => ({
9 | plugins: [react()],
10 |
11 | // Vite options tailored for Tauri development and only applied in `tauri dev` or `tauri build`
12 | //
13 | // 1. prevent vite from obscuring rust errors
14 | clearScreen: false,
15 | // 2. tauri expects a fixed port, fail if that port is not available
16 | server: {
17 | port: 1420,
18 | strictPort: true,
19 | host: host || false,
20 | hmr: host
21 | ? {
22 | protocol: "ws",
23 | host,
24 | port: 1421,
25 | }
26 | : undefined,
27 | watch: {
28 | // 3. tell vite to ignore watching `src-tauri`
29 | ignored: ["**/src-tauri/**"],
30 | },
31 | },
32 | }));
33 |
--------------------------------------------------------------------------------
/src/components/FreeHandPosition.css:
--------------------------------------------------------------------------------
1 | .mini-titles{
2 | width: 100%;
3 | text-align: center;
4 | margin-left: auto;
5 | margin-right: auto;
6 | font-size: 25px;
7 | align-content: center;
8 | }
9 | .right-freehand-container{
10 | display: flex;
11 | flex-direction: column;
12 | height: 100%;
13 | width: 20vw;
14 | }
15 | .freehand-function-buttons{
16 | width: 100%;
17 | height: 16%;
18 | padding:0px;
19 | }
20 | .scale-container{
21 | height: 36%;
22 | width: 100%;
23 | display: flex;
24 | flex-direction: column;
25 | justify-content: center;
26 | }
27 | .scale-container-mini{
28 | display: flex;
29 | flex-direction: row;
30 | }
31 | .scale-base-text{
32 | text-align: right;
33 | width: 50%;
34 | font-size: 20px;
35 | margin-top: auto;
36 | margin-bottom: auto;
37 | }
38 | .scale-input{
39 | width: 50%;
40 | font-size: 20px;
41 | padding-top: 0px;
42 | margin-top: auto;
43 | margin-bottom: auto;
44 | }
--------------------------------------------------------------------------------
/src/components/Popups/SingleErrorPopUp.tsx:
--------------------------------------------------------------------------------
1 | import { Dispatch, SetStateAction } from "react";
2 | import "./SingleErrorPopUp.css";
3 |
4 | export interface SingleError {
5 | showSingleError: boolean,
6 | setShowSingleError: Dispatch>,
7 | singleErrorText: string
8 | setSingleErrorText: Dispatch>
9 | }
10 | export const SingleErrorPopup: React.FC = ({ showSingleError, singleErrorText, setShowSingleError }) => {
11 | return (
12 |
13 |
14 |
Failed
15 |
16 | {singleErrorText}
17 |
18 |
19 |
20 | );
21 | };
22 | export default SingleErrorPopup;
--------------------------------------------------------------------------------
/src-tauri/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "display-settings-plus"
3 | version = "0.1.0"
4 | description = "A Tauri App"
5 | authors = ["you"]
6 | edition = "2021"
7 |
8 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
9 |
10 | [lib]
11 | # The `_lib` suffix may seem redundant but it is necessary
12 | # to make the lib name unique and wouldn't conflict with the bin name.
13 | # This seems to be only an issue on Windows, see https://github.com/rust-lang/cargo/issues/8519
14 | name = "display_settings_plus_lib"
15 | crate-type = ["staticlib", "cdylib", "rlib"]
16 |
17 | [build-dependencies]
18 | tauri-build = { version = "2", features = [] }
19 |
20 | [dependencies]
21 | tauri = { version = "2", features = ["protocol-asset"] }
22 | tauri-plugin-opener = "2"
23 | xrandr = { version = "^0", path = "./xrandr" }
24 | serde = { workspace = true }
25 | serde_json = { workspace = true }
26 | tokio = { version ="1.43.0", features = ["macros"] }
27 | tokio-macros = "2.5.0"
28 | xcap = "0.3.3"
29 | directories = "6.0.0"
30 | lazy_static = "1.5.0"
31 |
32 | [workspace.dependencies]
33 | serde = { version = "1", features = ["derive"] }
34 | serde_json = "1"
35 |
--------------------------------------------------------------------------------
/src/components/Loading.css:
--------------------------------------------------------------------------------
1 | @import url('https://fonts.googleapis.com/css?family=Inconsolata');
2 | * {
3 | margin: 0;
4 | padding: 0;
5 | box-sizing: border-box;
6 | }
7 |
8 | html, body {
9 | width: 100%;
10 | height: 100%;
11 | }
12 | body {
13 | background: rgb(11, 11, 20);
14 | font-family: 'Inconsolata', monospace;
15 | overflow: hidden;
16 | overflow-y: scroll;
17 | margin: 0px;
18 | }
19 |
20 | .loading-h1 {
21 | position: absolute;
22 | height: 40px;
23 | margin: auto;
24 | top: 10px;
25 | left: 0;
26 | right: 0;
27 | bottom: 0;
28 | text-transform: uppercase;
29 | text-align: center;
30 | letter-spacing: 0.1em;
31 | font-size: 14px;
32 | font-weight: lighter;
33 | color: white;
34 | span {
35 | display: none;
36 | }
37 | &::after {
38 | animation: txt 5s infinite;
39 | content: "";
40 | }
41 | }
42 |
43 | @keyframes cw {
44 | 0% {
45 | width: 0;
46 | height: 0;
47 | }
48 | 75% {
49 | width: 40px;
50 | height: 40px;
51 | }
52 | 100% {
53 | width: 0;
54 | height: 0;
55 | }
56 | }
57 |
58 | @keyframes txt {
59 | 0% {
60 | content: "LOADING.";
61 | }
62 | 50% {
63 | content: "LOADING..";
64 | }
65 | 100% {
66 | content: "LOADING...";
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/src/components/Popups/SingleErrorPopUp.css:
--------------------------------------------------------------------------------
1 | .single-error-popup {
2 | display: block;
3 | position: fixed;
4 | padding: 10px;
5 | width: 400px;
6 | left: 50%;
7 | margin-left: -200px;
8 | height: 200px;
9 | top: 50%;
10 | margin-top: -225px;
11 | z-index: 20;
12 | }
13 |
14 | .single-error-popup:after {
15 | position: fixed;
16 | content: "";
17 | top: 0;
18 | left: 0;
19 | bottom: 0;
20 | right: 0;
21 | background: rgba(0,0,0,0.5);
22 | z-index: -2;
23 | }
24 |
25 | .single-error-popup:before {
26 | position: absolute;
27 | content: "";
28 | top: 0;
29 | left: 0;
30 | bottom: 0;
31 | right: 0;
32 | border-style: double;
33 | border-radius: 25px;
34 | border-color: hotpink;
35 | background-color: rgb(11, 11, 20);
36 | z-index: -1;
37 | }
38 | .single-error-contents{
39 | display: flex;
40 | flex-direction: column;
41 | height: 135px;
42 | }
43 | .single-error-popup-title{
44 | margin-left: auto;
45 | margin-right: auto;
46 | height: 40px;
47 | }
48 | .single-error-text{
49 | margin-bottom: auto;
50 | }
51 | .single-error-accept-button{
52 | margin: auto;
53 | width: 100%;
54 | border-radius: 0px 0px 20px 20px;
55 | }
--------------------------------------------------------------------------------
/src/components/Popups/MassApplyUndoPopup.css:
--------------------------------------------------------------------------------
1 | .mass-apply-popup {
2 | display: block;
3 | position: fixed;
4 | padding: 10px;
5 | width: 300px;
6 | left: 50%;
7 | margin-left: -150px;
8 | height: 145px;
9 | top: 50%;
10 | margin-top: -100px;
11 | z-index: 20;
12 | }
13 |
14 | .mass-apply-popup:after {
15 | position: fixed;
16 | content: "";
17 | top: 0;
18 | left: 0;
19 | bottom: 0;
20 | right: 0;
21 | background: rgba(0,0,0,0.5);
22 | z-index: -2;
23 | }
24 |
25 | .mass-apply-popup:before {
26 | position: absolute;
27 | content: "";
28 | top: 0;
29 | left: 0;
30 | bottom: 0;
31 | right: 0;
32 | border-style: double;
33 | border-radius: 25px;
34 | border-color: hotpink;
35 | background-color: rgb(11, 11, 20);
36 | z-index: -1;
37 | }
38 | .mass-apply-contents{
39 | display: flex;
40 | flex-direction: column;
41 | height: 135px;
42 | }
43 | .mass-apply-header{
44 | display: flex;
45 | flex-direction: row;
46 | }
47 | .mass-apply-text{
48 | margin-bottom: auto;
49 | }
50 | .mass-apply-undo-button{
51 | margin: auto;
52 | width: 100%;
53 | height: 100%;
54 | color: hotpink;
55 | border-radius: 0px 0px 20px 20px;
56 | }
57 | .mass-apply-close-button{
58 | margin: auto;
59 | width: 100%;
60 | height: 100%;
61 | color: red;
62 | border-radius: 20px 20px 0px 0px;
63 | margin-right: 0px;
64 | }
--------------------------------------------------------------------------------
/src-tauri/xrandr/Cargo.toml:
--------------------------------------------------------------------------------
1 | # THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
2 | #
3 | # When uploading crates to the registry Cargo will automatically
4 | # "normalize" Cargo.toml files for maximal compatibility
5 | # with all versions of Cargo and also rewrite `path` dependencies
6 | # to registry (e.g., crates.io) dependencies.
7 | #
8 | # If you are reading this file be aware that the original Cargo.toml
9 | # will likely look very different (and much more reasonable).
10 | # See Cargo.toml.orig for the original contents.
11 |
12 | [package]
13 | edition = "2021"
14 | name = "xrandr"
15 | version = "0.2.0"
16 | authors = [
17 | "Rintse",
18 | "Daniel Franklin ",
19 | ]
20 | description = "Safe rust bindings to (some parts of) xrandr"
21 | readme = "README.md"
22 | keywords = [
23 | "xrandr",
24 | "libxrandr",
25 | "libxrandr2",
26 | "bindings",
27 | "linux",
28 | ]
29 | categories = [
30 | "os::linux-apis",
31 | "api-bindings",
32 | ]
33 | license = "MIT"
34 | repository = "https://github.com/danielzfranklin/xrandr-rs"
35 |
36 | [dependencies.indexmap]
37 | version = "1.6.2"
38 |
39 | [dependencies.itertools]
40 | version = "0.10.5"
41 |
42 | [dependencies.libc]
43 | version = "0.2.146"
44 |
45 |
46 | [dependencies]
47 | serde = { workspace = true }
48 | serde_json = { workspace = true }
49 |
50 | [dependencies.thiserror]
51 | version = "1.0.24"
52 |
53 | [dependencies.time]
54 | version = "0.3.20"
55 |
56 | [dependencies.x11]
57 | version = "2.18.2"
58 | features = [
59 | "xlib",
60 | "xrandr",
61 | ]
62 |
63 |
64 |
--------------------------------------------------------------------------------
/src/components/Presets.css:
--------------------------------------------------------------------------------
1 | .presets-top-container{
2 | height: 75px;
3 | }
4 | .presets-list-container{
5 | height: calc( 85% - 84px);
6 | overflow-y: scroll;
7 | }
8 | .presets-title{
9 | width: 100%;
10 | height: 25px;
11 | text-align: center;
12 | margin-left: auto;
13 | margin-right: auto;
14 | margin-top: 5px;
15 | margin-bottom: 5px;
16 | }
17 | .presets-add-button{
18 | height: 40px;
19 | width: 10px;
20 | }
21 | .presets-add-button:hover{
22 | color:#39FF14;
23 | display: inline-flex;
24 |
25 | align-items: center;
26 | text-align: center;
27 | }
28 | .preset-delete-button{
29 | width: 25%;
30 | }
31 | .preset-delete-button:hover{
32 | color:red;
33 | }
34 | .selected-preset-button{
35 | width: 75%;
36 | color:hotpink;
37 | }
38 | .unselected-preset-button{
39 | width: 75%;
40 | }
41 | /*https://codepen.io/savwiley/pen/xxVRqXX*/
42 | .presets-search-bar {
43 | width: 100%;
44 | padding: 10px;
45 | height: 40px;
46 | font-size: 18px;
47 | outline:none;
48 | background: linear-gradient(to left top, #000, #22132e) fixed;
49 | border: 2px solid rgba(255,255,255,0.2);
50 | color: rgba(255,255,255,0.8);
51 | transition: all 0.5s;
52 | }
53 |
54 | .presets-search-bar:hover {
55 | border: 2px solid rgba(255,255,255,0.5);
56 | }
57 | .presets-search-bar:focus {
58 | border: 2px solid rgba(255,255,255,0.5);
59 | background: linear-gradient(to left top, #000, #A64C79) fixed;
60 | }
61 |
62 | .overwrite-button{
63 | width: 100%;
64 | height: 15%;
65 | padding: 0px;
66 | border: 0px;
67 | }
--------------------------------------------------------------------------------
/src-tauri/tauri.conf.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://schema.tauri.app/config/2",
3 | "productName": "display-settings-plus",
4 | "version": "0.1.0",
5 | "identifier": "com.display-settings-plus.app",
6 | "build": {
7 | "beforeDevCommand": "npm run dev",
8 | "devUrl": "http://localhost:1420",
9 | "beforeBuildCommand": "npm run build",
10 | "frontendDist": "../dist"
11 | },
12 | "app": {
13 | "windows": [
14 | {
15 | "title": "display-settings-plus",
16 | "width": 800,
17 | "height": 600,
18 | "resizable": true
19 | }
20 | ],
21 | "security": {
22 | "csp": "default-src 'self' ipc: http://ipc.localhost asset://localhost; img-src 'self' asset: http://asset.localhost asset: asset://localhost data: blob:; worker-src 'self' blob:; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; font-src 'self' https://fonts.gstatic.com; script-src 'self' 'unsafe-eval';connect-src 'self' asset://localhost;connect-src 'self' asset://localhost ipc://localhost;"
23 | ,
24 | "assetProtocol": {
25 | "enable": true,
26 | "scope": ["$HOME/.config/display_settings_plus/screenshots/**"]
27 | }
28 | }
29 | },
30 | "bundle": {
31 | "active": true,
32 | "targets": "all",
33 | "shortDescription": "GUI for Xrandr built with Rust's Tauri and React.ts",
34 | "longDescription": "A GUI for those who use X11's display server. This application allows you to edit the location, rotation, ratio and rate of your monitors.",
35 | "icon": [
36 | "icons/32x32.png",
37 | "icons/128x128.png",
38 | "icons/128x128@2x.png",
39 | "icons/icon.icns",
40 | "icons/icon.ico"
41 | ]
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/src/components/Loaded.css:
--------------------------------------------------------------------------------
1 |
2 | .loadedMain {
3 | height: 100vh;
4 | display:flex;
5 | flex-direction: column;
6 | }
7 | .react-select{
8 | height: 150px;
9 | }
10 |
11 | .majorButtons{
12 | color: hotpink;
13 | font-size: 15px;
14 | height: 52px;
15 | border-color: white;
16 | padding-top: 8px;
17 | padding-bottom: 8px;
18 | border-bottom: 0px;
19 | }
20 | .majorButtons:hover{
21 | border-bottom: 1px;
22 | }
23 | /* CSS from button people https://getcssscan.com/css-buttons-examples */
24 | button {
25 | appearance: none;
26 | background-color: transparent;
27 | border: 1px solid #1A1A1A;
28 |
29 | box-sizing: border-box;
30 | color: #3B3B3B;
31 | cursor: pointer;
32 | display: inline-block;
33 | font-family: Roobert,-apple-system,BlinkMacSystemFont,"Segoe UI",Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";
34 | font-size: 16px;
35 | font-weight: 600;
36 | line-height: normal;
37 | margin: 0;
38 | min-height: 40px;
39 | min-width: 0;
40 | outline: none;
41 | padding: 16px 24px;
42 | text-align: center;
43 | text-decoration: none;
44 | transition: all 300ms cubic-bezier(.23, 1, 0.32, 1);
45 | user-select: none;
46 | -webkit-user-select: none;
47 | touch-action: manipulation;
48 | will-change: transform;
49 | }
50 |
51 | button:disabled {
52 | color: hotpink;
53 | pointer-events: none;
54 | }
55 |
56 | button:hover {
57 | color: hotpink;
58 | background-color: #1A1A1A;
59 | box-shadow: rgba(0, 0, 0, 0.25) 0 8px 15px;
60 | transform: translateY(-2px);
61 | }
62 |
63 | button:active {
64 | box-shadow: none;
65 | transform: translateY(0);
66 | }
67 | body{
68 | background: rgb(11, 11, 20);
69 | }
--------------------------------------------------------------------------------
/src/components/Popups/SimplePopUp.css:
--------------------------------------------------------------------------------
1 | .simplePopup {
2 | display: block;
3 | position: fixed;
4 | padding: 10px;
5 | width: 400px;
6 | left: 50%;
7 | margin-left: -200px;
8 | height: 450px;
9 | top: 50%;
10 | margin-top: -225px;
11 |
12 | z-index: 20;
13 | }
14 |
15 | .simplePopup:after {
16 | position: fixed;
17 | content: "";
18 | top: 0;
19 | left: 0;
20 | bottom: 0;
21 | right: 0;
22 | background: rgba(0,0,0,0.5);
23 | z-index: -2;
24 | }
25 |
26 | .simplePopup:before {
27 | position: absolute;
28 | content: "";
29 | top: 0;
30 | left: 0;
31 | bottom: 0;
32 | right: 0;
33 | z-index: -1;
34 | }
35 | .simplePopUpContents{
36 | display:flex;
37 | height: 100%;
38 | width: 100%;
39 | flex-direction: column;
40 | }
41 | .simplePopUpText{
42 | color: white;
43 | margin-left:auto;
44 | margin-bottom:auto;
45 | margin-right:auto;
46 | }
47 | /*https://css-loaders.com/spinner/ */
48 |
49 | .simpleLoader {
50 | width: 50px;
51 | padding: 8px;
52 | margin-left:auto;
53 | margin-top:auto;
54 | margin-right:auto;
55 | aspect-ratio: 1;
56 | border-radius: 50%;
57 | background: hotpink;
58 | --_m:
59 | conic-gradient(#0000 10%,#000),
60 | linear-gradient(#000 0 0) content-box;
61 | -webkit-mask: var(--_m);
62 | mask: var(--_m);
63 | -webkit-mask-composite: source-out;
64 | mask-composite: subtract;
65 | animation: l3 1s infinite linear;
66 | }
67 | @keyframes l3 {to{transform: rotate(1turn)}}
68 |
69 |
--------------------------------------------------------------------------------
/src-tauri/xrandr/src/monitor.rs:
--------------------------------------------------------------------------------
1 | use crate::output::Output;
2 | use crate::XHandle;
3 | use crate::XrandrError;
4 | use core::ptr;
5 | use std::slice;
6 | use x11::xrandr;
7 |
8 | // A wrapper that drops the pointer if it goes out of scope.
9 | // Avoid having to deal with the various early returns
10 | pub(crate) struct MonitorHandle {
11 | ptr: ptr::NonNull,
12 | count: i32,
13 | }
14 |
15 | impl MonitorHandle {
16 | pub(crate) fn new(handle: &mut XHandle) -> Result {
17 | let mut count = 0;
18 |
19 | let raw_ptr =
20 | unsafe { xrandr::XRRGetMonitors(handle.sys.as_ptr(), handle.root(), 0, &mut count) };
21 |
22 | if count == -1 {
23 | return Err(XrandrError::GetMonitors);
24 | }
25 |
26 | let ptr = ptr::NonNull::new(raw_ptr).ok_or(XrandrError::GetMonitors)?;
27 |
28 | Ok(Self { ptr, count })
29 | }
30 |
31 | pub(crate) fn as_slice(&self) -> &[xrandr::XRRMonitorInfo] {
32 | unsafe { slice::from_raw_parts_mut(self.ptr.as_ptr(), self.count as usize) }
33 | }
34 | }
35 |
36 | impl Drop for MonitorHandle {
37 | fn drop(&mut self) {
38 | unsafe { xrandr::XRRFreeMonitors(self.ptr.as_ptr()) };
39 | }
40 | }
41 |
42 | #[derive(Debug)]
43 | #[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))]
44 | pub struct Monitor {
45 | pub name: String,
46 | pub is_primary: bool,
47 | pub is_automatic: bool,
48 | pub x: i32,
49 | pub y: i32,
50 | pub width_px: i32,
51 | pub height_px: i32,
52 | pub width_mm: i32,
53 | pub height_mm: i32,
54 | /// An Output describes an actual physical monitor or display. A [`Monitor`]
55 | /// can have more than one output.
56 | pub outputs: Vec