How do I set screen resolution for a specific program?

2,099

You can use the following python script to start your application at a given resolution:

#!/usr/bin/env python3

import argparse
import re
import subprocess
import sys

parser = argparse.ArgumentParser()
parser.add_argument('--output', required=True)
parser.add_argument('--resolution', required=True)
parser.add_argument('APP')
args = parser.parse_args()

device_context = ''    # track what device's modes we are looking at
modes = []             # keep track of all the devices and modes discovered
current_modes = []     # remember the user's current settings

# Run xrandr and ask it what devices and modes are supported
xrandrinfo = subprocess.Popen('xrandr -q', shell=True, stdout=subprocess.PIPE)
output = xrandrinfo.communicate()[0].decode().split('\n')

for line in output:
    # luckily the various data from xrandr are separated by whitespace...
    foo = line.split()

    # Check to see if the second word in the line indicates a new context
    #  -- if so, keep track of the context of the device we're seeing
    if len(foo) >= 2:  # throw out any weirdly formatted lines
        if foo[1] == 'disconnected':
            # we have a new context, but it should be ignored
            device_context = ''
        if foo[1] == 'connected':
            # we have a new context that we want to test
            device_context = foo[0]
        elif device_context != '':  # we've previously seen a 'connected' dev
            # mode names seem to always be of the format [horiz]x[vert]
            # (there can be non-mode information inside of a device context!)
            if foo[0].find('x') != -1:
                modes.append((device_context, foo[0]))
            # we also want to remember what the current mode is, which xrandr
            # marks with a '*' character, so we can set things back the way
            # we found them at the end:
            if line.find('*') != -1:
                current_modes.append((device_context, foo[0]))

for mode in modes:
    if args.output == mode[0] and args.resolution == mode[1]:
        cmd = 'xrandr --output ' + mode[0] + ' --mode ' + mode[1]
        subprocess.call(cmd, shell=True)
        break
else:
    print('Unable to set mode ' + args.resolution + ' for output ' + args.output)
    sys.exit(1)

subprocess.call(args.APP, shell=True)

# Put things back the way we found them
for mode in current_modes:
    cmd = 'xrandr --output ' + mode[0] + ' --mode ' + mode[1]
    subprocess.call(cmd, shell=True)

Save the above script (e.g as my-script.py) and make it executable:

chmod +x my-script.py

To set a resolution of 1280x1024 and start gedit just type:

./my_script.py --output VGA1 --resolution 1280x1024 gedit

To avoid typing this command everytime, save the script in your home directory and add the following lines to your .bashrc:

alias my_bracket='~/my_script.py --output VGA1 --resolution 1280x1024 gedit'

Or even better, modify the desktop file that the package installs in /usr/local/share/applications/brackets.desktop.

sudo gedit /usr/local/share/applications/brackets.desktop

And replace the file content with the new lines below:

[Desktop Entry]
Name=Brackets
Type=Application
Categories=Development
Exec=/home/mushir/my_script.py --output VGA1 --resolution=1280x1024 /opt/brackets/brackets
Icon=brackets
MimeType=text/html;
Keywords=Text;Editor;Write;Web;Development;

Source: Checkbox xrandr_cycle script

Share:
2,099

Related videos on Youtube

Ryenra
Author by

Ryenra

Updated on September 18, 2022

Comments

  • Ryenra
    Ryenra over 1 year

    I'm building an App (Electron based) where I need to get an information from a third party website before the main window is created, but I'm a little bit confused about security measures. I'm using axios to do the HTTP request inside the main process because it is promise based and I can create the window after the website is fetched. My concerns are:

    Enabling nodeIntegration is not good when messing with the renderer process because of cross-site-scripting attack. Should I include all nodejs modules in a preload.js like the following, for example.

    index.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="Content-Security-Policy" content="script-src 'self';">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Viewer</title>
    </head>
    <body>
        <div id="box">
            <form id='fo'>
                    <input type="text" id="num">
                    <button type="button" id="bttn">Random</button>
            </form>
        </div>
        <script src="renderer.js"></script>
    </body>
    </html>
    

    main.js

    const electron = require('electron');
    const cheerio = require('cheerio');
    const axios = require('axios').default;
    const path = require('path');
    const {app, BrowserWindow, ipcMain, Menu, MenuItem,session} = electron;
    
    let win;
    let url = 'sampletext';
    
    function createWindow() {
        win = new BrowserWindow({
            width: 400,
            height: 250,
            webPreferences:{
                nodeIntegration: false,
                contextIsolation: true,
                preload: path.join(app.getAppPath(), 'preload.js')
            },
            show: false,                        
        });
    
        win.loadFile('index.html');
    
        win.once('ready-to-show', () =>{
            win.show();
        });
    
        win.on('closed', () =>{
            win = null;
        });
    }
    
    app.whenReady().then(getRequest().then(res => {
        const $ = cheerio.load(res);
        if($('infoNeeded')){
            random = get_numbers($('infoNeeded').attr('href'));
        }
        createWindow();
    }));
    
    app.on('window-all-closed', () =>{
        app.quit();
    });
    
    function getRequest() {
        return axios.get(url).then(res =>  res.data).catch(err => console.log(err));
    }
    

    preload.js

    //Instead of using getRequest() on main.js use this file
    const electron = require('electron');
    const remote = require('electron').remote;
    const cheerio = require('cheerio');
    const axios = require('axios').default;
    let url = 'sampletext';
    
    //So I can use it in renderer.js
    window.getReq = function () {
        return axios.get(url).then(res =>  res.data).catch(err => console.log(err));
    }
    
    window.parseInfo = function (data) {
        const $ = cheerio.load(data);
        if($('infoNeeded')){
           return random = get_numbers($('infoNeeded').attr('href'));
        }
        return;
    }
    
    //Preload first request
    window.getReq().then(doStuffHere);
    

    renderer.js

    let info;
    
    //Keep updating the info
    
    setInterval( () =>{
        window.getReq().then(data => {
            info = window.parseInfo(data);
        });
    }, 10000);
    

    1) Is it ok to do nodejs require inside main process? If not, what's the secure way of doing it?

    2) May I make HTTP requests inside main process? If yes, should I send a CSP header when doing so?

    3) Instead of doing the request inside the main.js, should I use "webPreferences: preload" property and make the first HTTP request inside preload.js (Just like the above example) ? (I need to get the info before sending it to renderer.js)

    I've already read https://www.electronjs.org/docs/tutorial/security, but I couldn't grasp their teaching. If you could provide an answer for how and when to use preload.js and CSP header I'll be very grateful.

    • Sh1d0w
      Sh1d0w about 9 years
      Please explain with more details the case, why do you need to do that?
    • Jacob Vlijm
      Jacob Vlijm about 9 years
      could you mention the program in question, the output of xrandr and the desired resolution?
    • Misho21
      Misho21 about 9 years
      Just edited my question !
    • Misho21
      Misho21 about 9 years
      I know that brackets is build mainly with html and css .. if just I can hack the code and edit it that will be another way to do it but I don't know how to start
    • Mike 'Pomax' Kamermans
      Mike 'Pomax' Kamermans about 4 years
      At the very least use ES modules, so your code doesn't execute until its dependencies are loaded, and use the defer attribute on your <script> elements.
  • Misho21
    Misho21 about 9 years
    thanks .. but there is two issues about this script : every time I need to run this command and this not very convenient for me and after I close the program my screen doesn't go back automatically to the default resolution
  • Sylvain Pineau
    Sylvain Pineau about 9 years
    @Misho21: I've fixed the settings recovery issue
  • Misho21
    Misho21 about 9 years
    thanks now it's working ! I wonder if there is away to start this script automatically every time I run the program so it won't be necessary to run it from terminal every time ?
  • Sylvain Pineau
    Sylvain Pineau about 9 years
    @Misho21: Please check my new edit
  • Misho21
    Misho21 about 9 years
    there is .bashrc file in home and another one in /etc tell me which one to edit please
  • Sylvain Pineau
    Sylvain Pineau about 9 years
    @Misho21: Forget the (home) .bashrc update and prefer the .desktop if you're not starting brackets from a terminal
  • Misho21
    Misho21 about 9 years
    one last request I promise ! can I use this script to force Plymouth resolution ??
  • Sylvain Pineau
    Sylvain Pineau about 9 years
    @Misho21: You can't, plymouth operates earlier in the boot process and uses itw own configuration files.