Score:1

How can i move a window to a specific monitor (Ubuntu 20.04)?

af flag

How do I move a window to a specific monitor with code? I have two screens where one needs to run an app in full screen, and the other needs to play a video in full screen.

HuHa avatar
es flag
That `wmctrl` that somebody (you?) added as a tag is a good starting point IMHO. Install that package (`sudo apt install wmctrl`) and look at the man page (`man wmctrl).
Score:1
ru flag

You can use xdotool to achieve what you want.

I don't think there is any setting to move to one screen or another, you just need to set each window position (x and y position) and geometry (size). For example, run the following command in a terminal window

xdotool search --name "WINDOW TITLE HERE" getwindowgeometry

And then move the window around and between different monitors and you will see that it's just a different (top-left) x/y position depending on your monitor setup and resolution.

So you can experiment and code scripts to get the relevant window ID's and then set the position with the windowmove command and geometry with the windowsize command.

codlord avatar
ru flag
I have just seen your question is tagged with `wmctrl`. I am not too familiar with that but perhaps it's the same sort of position/geometry. Try `wmctrl -p -G -l` to list windows with geometry and move between monitors to see what changes and how it changes.
Score:0
nf flag

I created this python script that reads a configuration json file and places each window to its desired place.

sudo apt install xdotool
git clone [email protected]:cix-code/win-pos.git
cd win-pos
cp sample.config.json config.json
nano config.json

# Run it this way or set it as delayed startup script
python3 winpos.py

Configuration example:

// Postitions the Spotify window on the second screen from the left, 
// on the second desktop centerly aligned.
{
    "name": "Spotify",
    "search_name": "^Spotify$",
    "screen": 1,
    "desktop": 1,
    "width": "50%",
    "height": "60%",
    "align": "center center"
},

The script simply runs the relevant xrandr, xdotool and pgrep commands to retrieve the screens layout, get the window ID and place the windows to their desired place.

Score:0
af flag

I created this rather complicated code to find the windows i wanted to move to a specific screen determined by the width in mm of the monitor (it will also resize to the correct resolution and set the app fullscreen):

#!/usr/bin/env python3
import subprocess
import time


def get(cmd): return subprocess.check_output(cmd).decode('utf-8')


def adjust_resolution(name, res):  # name = DP-2, res: 1920x1080
    get(['xrandr', '--output', name, '--mode', res])


def edit_window(monitor, window_name, function):
    print('moving', window_name, 'to', monitor)
    get(['wmctrl', '-F', '-r', window_name, '-e', '100,' +
        monitor['x'] + ',' + monitor['y'] + ',600,600'])
    get(['wmctrl', '-F', '-r', window_name, '-b', function])


def get_monitors():
    screendata = [l.split() for l in get(['xrandr', '--current']
                                         ).replace('primary', '').splitlines() if ' connected' in l]
    monitors = []

    for i in range(len(screendata)):
        monitor = dict()
        [size, x, y] = screendata[i][2].split('+')
        monitor = {
            'name': screendata[i][0],
            'width': screendata[i][-3],
            'height': screendata[i][-1],
            'size': size,
            'x': x,
            'y': y
        }
        monitors.append(monitor)

    return monitors


def find_element_where(elements, key, value):
    return next((item for item in elements if item[key] == value), None)


def window_info_to_dict(info):
    _, _, x, y, width, height, _, *name = info.split()
    return {'x': x, 'y': y, 'width': width, 'height': height, 'name': ' '.join(name)}


def get_window_info():
    return list(map(window_info_to_dict, get(['wmctrl', '-l', '-G']).splitlines()))


# Constants:
main_monitor_width = '256mm'
controller_app = 'name_of_app'
video_player = 'VLC media player'
correct_resolution = '1920x1080'

# Variables:
did_remove_fullscreen = False

while True:
    try:
        # Get monitors:
        monitors = get_monitors()
        main_monitor = next(
            (monitor for monitor in monitors if monitor['width'] == main_monitor_width), None)
        secondary_monitor = next(
            (monitor for monitor in monitors if monitor['width'] != main_monitor_width), None)

        # print(main_monitor)
        # print(secondary_monitor)

        # Get windows:
        window_info = get_window_info()

        controller_app_window_info = find_element_where(
            window_info, 'name', controller_app)
        video_player_window_info = find_element_where(
            window_info, 'name', video_player)

        # Check if secondary monitor is the right size:
        if secondary_monitor and secondary_monitor['size'] != correct_resolution:
            print('Wrong resolution', secondary_monitor)
            adjust_resolution(secondary_monitor['name'], correct_resolution)

        # print(controller_app_window_info)
        # print(video_player_window_info)

        if main_monitor:
            if controller_app_window_info['x'] != main_monitor['x'] or controller_app_window_info['y'] != main_monitor['y'] or controller_app_window_info['width'] != '1920' or controller_app_window_info['height'] != '1080':
                print('Controller app is not positioned correctly')
                edit_window(main_monitor, controller_app, 'add,fullscreen')
        else:
            print('No primary monitor')

        if secondary_monitor:
            if video_player_window_info['x'] != secondary_monitor['x'] or video_player_window_info['y'] != secondary_monitor['y'] or video_player_window_info['width'] != '1920' or video_player_window_info['height'] != '1080':
                print('Video player is not positioned correctly')
                edit_window(secondary_monitor, video_player, 'add,fullscreen')
                did_remove_fullscreen = False
        else:
            print('No secondary monitor')
            if main_monitor and not did_remove_fullscreen:
                edit_window(main_monitor, video_player, 'remove,fullscreen')
                did_remove_fullscreen = True

    except Exception as e:
        print('An error occured', e)

    time.sleep(10)
mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.