2 votes

Comment faire en sorte qu'une deuxième fenêtre s'affiche sur le côté opposé de l'écran ?

Je viens de Windows 10, bien que j'ai commencé (et accepté) la façon dont Ubuntu fonctionne, il y a encore quelques choses que j'aime dans Windows 10, la fonctionnalité en question ici est la façon dont si je snap un Windows à l'extrême droite de l'écran, il prend la moitié droite de l'affichage (qui est également similaire dans Ubuntu), mais une autre application en arrière-plan prend la moitié gauche de l'affichage et n'a pas besoin de le faire manuellement.

Screenshot

Dans cette image, si je fais glisser les fenêtres du navigateur vers la droite, la fenêtre Nautilus ne sera pas affectée par cette action, mais je veux qu'elle (la fenêtre Nautilus) se déplace vers la gauche.

Détails

  • Ubuntu 17.04
  • Le goût des gnomes

Mise à jour

résultat de la fillscreen.py script

1st result

au premier essai écran de remplissage La notification est arrivée (je n'ai pas pu la capturer) et elle a déplacé la 2ème fenêtre (fenêtre de droite) dans une boîte, et la 1ère fenêtre n'a pas été affectée du tout.

2nd result

au deuxième essai, ce décalage était présent, mais il a fonctionné (et il fonctionne surtout)

1voto

Jacob Vlijm Points 78990

Remarque importante !

Le script ci-dessous fera exactement ce que vous décrivez. sur les deux plus jeunes Windows, c'est-à-dire les deux Windows qui ont été créés en dernier.

Le script, comportement

  • Le script agit sur traînage l'une des deux fenêtres "les plus récentes" à l'une des deux zones de l'écran, comme le montre l'image.

    enter image description here

    La zone est délibérément pas dans l'angle, pour s'assurer qu'il n'interfère pas avec l'accrochage "normal" de la fenêtre.

  • Si la fenêtre est glissée sur l'une ou l'autre des zones, le script attend 0,15 seconde pour voir si la souris est toujours dans la même position, pour être sûr de ne pas agir si l'utilisateur était "en route" vers le coin de l'écran pour le snapping normal de la fenêtre.

  • Ensuite, la fenêtre déplacée est placée dans la moitié de l'écran où se trouve la zone, la deuxième fenêtre est placée de l'autre côté de l'écran.

    1. Faites glisser la fenêtre vers la zone

    enter image description here

    2. la fenêtre s'enclenche, l'autre s'enclenche sur le site opposé

    enter image description here

  • enfin, en guise de confirmation, une notification s'affiche pendant trois secondes :

    enter image description here

    Voir le script en action

Le script et sa configuration

La configuration implique deux éléments :

  • le script :

    #!/usr/bin/env python3
    import sys
    import os
    import subprocess
    import time
    from operator import itemgetter
    from itertools import groupby
    import math
    
    #--- set your preferences below: padding between windows, margin(s)
    cols = 2; rows = 1; padding = 20; left_margin = 0; top_margin = 30
    #---
    
    fpath = os.path.dirname(os.path.abspath(__file__))
    n_wins = cols*rows
    
    def get_spot(pos):
        # get the resolution
        scrdata = get("xrandr").split(); resindex = scrdata.index("connected")+2
        res = [int(n) for n in scrdata[resindex].split("+")[0].split("x")]
        # list the corners, could be more elegant no doubt
        corners = [[0, res[1]], [res[0], res[1]]]
        diff = [int(math.sqrt(sum([(c[i]-pos[i])**2 for i, n in enumerate(res)])))\
                for c in corners]
        return diff
    
    def get(cmd):
        try:
            return subprocess.check_output(cmd).decode("utf-8")
        except subprocess.CalledProcessError:
            pass
    
    def get_res():
        xr = get("xrandr").split(); pos = xr.index("current")
        return [int(xr[pos+1]), int(xr[pos+3].replace(",", "") )]
    
    def get_pos():
        return [int(s.split(":")[1]) for s in get(["xdotool", "getmouselocation"]).split()[:2]]
    
    def check_window(w_id):
        w_type = get(["xprop", "-id", w_id])
        if " _NET_WM_WINDOW_TYPE_NORMAL" in w_type:
            return True
        else:
            return False
    
    def confirm():
        val = False
        mouseloc = get_spot(get_pos())
        match = [mouseloc.index(n) for n in mouseloc if 50 < n < 400]
        if match:
            time.sleep(0.15)
            val = True if get_spot(get_pos()) == mouseloc else False
        return val, match
    
    def arrange_wins(active, side):
        # get resolution
        res = get_res()
        # define (calculate) the area to divide
        area_h = res[0] - left_margin; area_v = res[1] - top_margin
        # create a list of calculated coordinates
        x_coords = [int(left_margin+area_h/cols*n) for n in range(cols)]
        y_coords = [int(top_margin+area_v/rows*n) for n in range(rows)]
        coords = sum([[(cx, cy) for cx in x_coords] for cy in y_coords], [])
        # calculate the corresponding window size, given the padding, margins, columns and rows
        w_size = [str(int(area_h/cols - padding)), str(int(area_v/rows - padding))]
        # find windows of the application, identified by their pid
        active = hex(int(get(["xdotool", "getactivewindow"])))
        active = active[:2]+(10-len(active))*"0"+active[2:]
        wlist = [w.split()[0] for w in get(["wmctrl", "-l"]).splitlines()]
        w_list = [w for w in wlist if check_window(w) == True][-n_wins:]
        try:
            w_list = w_list[::-1] if w_list.index(active) != side else w_list
        except ValueError:
            pass
        else: 
            print(w_list)
            # remove possibly maximization, move the windows
            for n, w in enumerate(w_list):
                data = (",").join([str(item) for item in coords[n]])+","+(",").join(w_size)
                cmd1 = "wmctrl -ir "+w+" -b remove,maximized_horz"
                cmd2 = "wmctrl -ir "+w+" -b remove,maximized_vert"
                cmd3 = "wmctrl -ir "+w+" -e 0,"+data
                for cmd in [cmd1, cmd2, cmd3]:
                    subprocess.Popen(["/bin/bash", "-c", cmd])
    
    wins1 = []
    
    while True:
        time.sleep(0.5)
        windata = get(["wmctrl", "-lG"])
        if windata:
            wins2 = [[l[0], l[2]] for l in [
                ln.split() for ln in windata.splitlines()]
                       ]
            # combined window locations old/new, grouped to see if moved
            winlocs = sorted(wins1 + wins2, key = itemgetter(0))
            test = [[item, [item[1] for item in list(occ)]] \
                    for item, occ in groupby(winlocs, itemgetter(0))]
            for item in test:
                # old loc, new loc of window
                locs = item[1]
                # window moves?
                if locs.count(locs[0]) != len(locs):
                    args = confirm()
                    if args[0]:
                        arrange_wins(item[0], args[1][0])
                        subprocess.Popen([
                            "notify-send", "-i", os.path.join(
                                fpath, "left.png"), "Fill screen"
                            ])
                        time.sleep(3)
                        subprocess.Popen(["pkill", "notify-osd"])
            wins1 = wins2
  • une icône à afficher dans la notification

    enter image description here

Configuration

  1. Installez les deux xdotool y wmctrl

  2. Copiez le script dans un fichier vide, enregistrez-le sous le nom de fillscreen.py dans un dossier dédié quelque part.

  3. Cliquez avec le bouton droit de la souris sur l'icône ci-dessus et enregistrez-la sous (exactement). left.png dans un seul et même dossier que le script. .

  4. Maintenant, ouvrez un terminal, exécutez la commande :

    python3 /path/to/fillscreen.py

    Notez que cette fenêtre de terminal est l'une des deux fenêtres que le script va casser. Dessinez le terminal sur l'une des zones à gauche ou à droite. Les deux fenêtres les plus récentes devraient s'enclencher.

  5. Si tout fonctionne bien, ajoutez le script aux applications de démarrage : Dash > Startup Applications > Add. Ajoutez la commande :

    /bin/bash -c "sleep 10 && python3 /path/to/fillscreen.py"

Note

En raison du fait que le script n'agit que sur le mouvement de la fenêtre, et qu'ensuite toutes les autres actions dépendent de la situation, le script est très faible en jus. Bien plus bas que ce à quoi je m'attendais lorsque j'ai commencé à travailler dessus.

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X