5

I have connected a LCD to my laptop. When I try to open a file in Nautilus, the target application opens in my laptop display, rather than the second display (in which nautilus window is open).

I don't want to change the default display. I want to open windows in the display I am working in. If my file manager is in laptop display, I want the apps to open in laptop display. If my file manager is in external display, I expect to open files there.

The output of xrandr

Screen 0: minimum 320 x 200, current 3286 x 1080, maximum 32767 x 32767
eDP1 connected 1366x768+0+0 (normal left inverted right x axis y axis) 256mm x 144mm
   1366x768       60.1*+
   1360x768       59.8     60.0  
   1024x768       60.0  
   800x600        60.3     56.2  
   640x480        59.9  
VGA1 disconnected (normal left inverted right x axis y axis)
HDMI1 connected primary 1920x1080+1366+0 (normal left inverted right x axis y axis) 527mm x 296mm
   1920x1080      60.0*    50.0     59.9  
   1920x1080i     60.1     50.0     60.0  
   1680x1050      59.9  
   1280x1024      75.0     60.0  
   1440x900       59.9  
   1280x960       60.0  
   1280x800       59.9  
   1152x864       75.0  
   1280x720       60.0     50.0     59.9  
   1440x576i      50.1  
   1024x768       75.1     70.1     60.0  
   1440x480i      60.1     60.1  
   832x624        74.6  
   800x600        72.2     75.0     60.3     56.2  
   720x576        50.0  
   720x480        60.0     59.9  
   640x480        75.0     72.8     66.7     60.0     59.9  
   720x400        70.1  
DP1 disconnected (normal left inverted right x axis y axis)
HDMI2 disconnected (normal left inverted right x axis y axis)
VIRTUAL1 disconnected (normal left inverted right x axis y axis)
  • 1
    Is very well doable, but have to run, Will post later if no one posted a solution in between. To possible voters, @EdiD : this has nothing to do with setting default monitor, this one is dynamically changing. – Jacob Vlijm Apr 16 '16 at 12:19
  • @JacobVlijm I added the output of xrandr. – Googlebot Apr 17 '16 at 8:30
  • @JacobVlijm sorry for my delay, I am trying different methods. I expect to install Ubuntu 16.04 on a new computer too. I will post all the results here. – Googlebot Apr 19 '16 at 17:00
  • @JacobVlijm one question, many possible solutions. I try to find a way easier than using a script. – Googlebot Apr 19 '16 at 18:09
  • 1
    See my script-less solution here : askubuntu.com/a/764528/295286 – Sergiy Kolodyazhnyy Apr 28 '16 at 19:28
7

The behaviour you describe (opening the window on the current screen) should be the default behaviour, On my 14.04 it is like that.

Due to minor incompatibilities with some graphics driver/GPU combinations, "peculiarities" might occur in some cases. If there is no "clean" option available (fix), you can use the workaround below.
It exists of a background script, looking for new windows to appear. In case a new window exists, the script compares the window position to the current mouse position. If both the mouse and the new window are not on the same screen, the window is moved, using the xdotool windowmove` command.

Is a background script a bad idea?

If you do not need a background script, don't use it.
At the same time: if it adds important functionality and/or saves you time, It would be silly not to, if the script is well organized and therefore "low on fuel".

As a reference: on both my laptop and my Desktop, I constantly run at least 5 background scripts + occasionally some additional ones for testing purposes, without any notice.

What is done to save fuel:

  1. The script has a variable loop cycle
    Once per 10 seconds, the script checks for the second screen to be connected. If not, the script skips the whole window check- procedure and re- checks after 10 seconds. This means that the script only acts if a second screen is attached. Once a second screen is connected, within 10 seconds, the loop is changed to a period of 2 seconds.
  2. All (next) actions the script takes are conditional
    e.g. the mouse position is only checked if there are new windows etc.

All together, on my system I could not notice nor measure any additional load, as a result of the script.

The script

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

def get(cmd):
    try:
        return subprocess.check_output(cmd).decode("utf-8").strip()
    except subprocess.CalledProcessError:
        pass

def screen_limit():
    screendata = [s for s in get("xrandr").split() if s.count("+") == 2]
    if len(screendata) == 2:
        return int([s.split("x")[0] for s in screendata if "+0+0" in s][0])

wd1 = get(["wmctrl", "-lG"])

t = 0
while True:
    time.sleep(2)
    # once per 10 seconds, check for a second screen
    if t == 0: 
        while True:
            rightside = screen_limit()
            # if no second screen, skip the procedure
            if rightside == None:
                time.sleep(10)
            else:
                break
    wd2 = get(["wmctrl", "-lG"])
    # check for buggy wmctrl
    if all([wd2 != None, wd1 != None]):
        wins = [w.split() for w in wd2.splitlines()]
        # check for new windows
        relevant = [w for w in wins if not w[0] in wd1]
        if relevant:
            # if new windows appeared, see if they match the mouse pos
            mousepos = int(get([
                "xdotool", "getmouselocation"
                ]).split()[0].split(":")[1])
            for w in relevant:
                check = [mousepos < rightside, int(w[2]) < rightside]
                if check[0] != check[1]:
                    # if mouse and window are not on the same screen > move
                    if check[0] == False:
                        cmd = ["xdotool", "windowmove", w[0],
                            str(int(w[2]) + rightside), w[3]]                    
                    else:
                        cmd = ["xdotool", "windowmove", w[0],
                            str(int(w[2]) - rightside), w[3]]
                    subprocess.Popen(cmd)
    wd1 = wd2
    t = 0 if t == 10 else t
    t += 1

How to use

  1. The script needs both wmctrl and xdotool. Run in a terminal:

    sudo apt-get install xdotool wmctrl
    
  2. Copy the script into an empty file, save it as move_windows.py
  3. Test- run the script by the command:

    python3 /path/to/move_windows.py
    
  4. If all works as expected, add it to Startup Applications: Dash > Startup Applications > Add. Add the command:

    /bin/bash -c "sleep 15 && python3 /path/to/move_windows.py"
    
  • This is a really good answer. I was thinking that Applications were following the mouse. Terminal will follow the mouse, but applications like LibreOffice, the splash screen followed the mouse, but the application followed the default monitor. +1 =) – Terrance Apr 24 '16 at 7:42

Your Answer

By clicking "Post Your Answer", you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.