Czy w Gnome-Terminal jest dostępna komenda lub jakaś powłoka z kartami do otwierania nowej karty?

11

Nie szukam skrótu klawiaturowego, raczej chcę polecenia dla:

  • Nowe okno
  • Nowa karta
  • Zamknij bieżącą kartę lub okno
  • Maksymalizuj okno powłoki
  • Minimalizuj okno powłoki
  • Przenieś Shell na inne miejsce do pracy
  • Przełącz kartę

I w zasadzie coś takiego. Zapamiętaj; Nie chcę skrótów, ale raczej rzeczywiste polecenia. Powodem tego jest to, że mogę korzystać z funkcji aliasu.

Akiva
źródło
1
Czy python jest z tobą w porządku?
Sergiy Kolodyazhnyy 18.09.16
4
„Zamknij bieżącą kartę” - to polecenie nazywa się „wyjście”: D
egmont
„Nie chcę skrótów [...], aby móc korzystać z funkcji aliasu” - czy mógłbyś to rozwinąć? Jakiej dokładnej przewagi oczekujesz zamiast dobrze znanych skrótów? Na czym polega problem lub brak funkcji w skrótach? Myślę, że są właściwym podejściem do tego, czego szukasz.
egmont
@egmont Jestem uzależniony od Vima, jeśli ma to jakiś sens.
Akiva
Powiedzmy na przykład, że dla Maximize zamiast klawisza skrótu menedżera okien, który działa dla wszystkich rodzajów okien (przeglądarki, edytora obrazów, edytora tekstu itp.) We wszystkich stanach (tj. Cokolwiek robisz w nich), „ d wolę mieć polecenie, które działa tylko dla terminala i żadnej innej aplikacji, i tylko wtedy, gdy nie uruchamia żadnego polecenia wewnątrz (oczywiście poza domyślną powłoką). Nie, przepraszam, ten pomysł wciąż nie ma dla mnie większego sensu :(
egmont

Odpowiedzi:

14

Nie możesz tego domyślnie robić w Gnome-Terminal, przynajmniej przy użyciu surowych poleceń.

Możesz jednak pisać skrypty wywołujące skróty klawiaturowe, które mogą to zrobić. Pamiętaj, że potrzebujesz xdotooltego:sudo apt install xdotool

  • Nowe okno : Uruchom nowe okno terminala za pomocą nw
    Możemy to zrobić za pomocą just gnome-terminal.
    Dodaj do.bashrc :

    echo "alias nw=gnome-terminal" >> ~/.bashrc
  • Nowa karta : Uruchom nową kartę za pomocą nt
    Możemy to zrobić za pomocą xdotool getactivewindow $(xdotool key ctrl+shift+t)
    Dodaj do.bashrc :

    echo "alias nt='xdotool getactivewindow $(xdotool key ctrl+shift+t)'" >> .bashrc
  • Zamknij zakładkę : ponownie zamknij bieżącą kartę lub okno za pomocą ct
    xdotoolostrzeżeń: xdotool getactivewindow $(xdotool key ctrl+shift+w)
    Dodaj do.bashrc :

    echo "alias ct='xdotool getactivewindow $(xdotool key ctrl+shift+w)'" >> .bashrc
  • Maksymalizuj okno : Maksymalizuj całe okno za pomocą maw
    Możemy wmctrltutaj: wmctrl -r :ACTIVE: -b toggle,maximized_vert,maximized_horz
    Dodaj do.bashrc :

    echo "alias maw='wmctrl -r :ACTIVE: -b toggle,maximized_vert,maximized_horz'" >> .bashrc
  • Minimalizuj okno : Zminimalizuj całe okno za pomocą miw
    Możemy użyć xdotoolponownie: xdotool windowminimize $(xdotool getactivewindow)
    Dodaj do.bashrc :

    echo "alias miw='xdotool windowminimize $(xdotool getactivewindow)'" >> .bashrc
  • Przenieś do obszaru roboczego : Przenieś okno do innego obszaru roboczego za pomocą mtw <id>
    To byłoby ledwo możliwe w skryptach powłoki i znacznie wykracza poza moje osobiste doświadczenia. Poleciłbym w tym celu użyć skryptu Serga, ponieważ tak naprawdę działa on od teraz. Ach, zalety Compiz.

Kaz Wolfe
źródło
7

Wprowadzenie

Skrypt przedstawiony w tej odpowiedzi pozwala użytkownikowi kontrolować okno terminala za pomocą jednego polecenia i listy opcji. Jest prosty w użyciu i kompatybilny z dowolnym emulatorem terminali o podobnych skrótach klawiszowych gnome-terminal. Opcje przesuwania mogą być używane także z innymi terminalami, ale otwarcie tych zakładek nie jest gwarantowane dla tych terminali.

Skrypt obejmuje otwieranie kart, otwieranie okien, przechodzenie do obszaru roboczego w dół, prawo obszaru roboczego, określonego obszaru roboczego, do którego odnosi się liczba całkowita, minimalizowanie, maksymalizowanie i maksymalizowanie okna. Jedyną rzeczą, której skrypt nie obejmuje, jest zamknięcie karty / okna po prostu dlatego, że każdy emulator powłoki / terminala ma już dla niego polecenie - exitlub alternatywnie za pomocą CtrlDskrótu.

!!! UWAGA: konieczne będzie xdotoolprzełączanie obszaru roboczego i otwieranie kart. Zainstaluj za pośrednictwem sudo apt-get install xdotool. Jeśli wolisz nie instalować dodatkowych pakietów, pamiętaj, że przełączanie obszaru roboczego i kart nie będzie działać , ale inne opcje będą działać .

Stosowanie:

Wszystkie argumenty windowctrl.pysą opcjonalne, więc można ich używać osobno lub potencjalnie razem. Jak pokazuje -hopcja.

$ ./windowctrl.py -h                                                                               
usage: windowctrl.py [-h] [-w] [-t] [-m] [-M] [-u] [-v VIEWPORT] [-r] [-d]

Copyright 2016. Sergiy Kolodyazhnyy.

    Window control for terminal emulators. Originally written
    for gnome-terminal under Ubuntu with Unity desktop but can 
    be used with any other terminal emulator that conforms to 
    gnome-terminal keybindings. It can potentially be used for 
    controlling other windows as well via binding this script
    to a keyboard shortcut.

    Note that --viewport and --tab options require xdotool to be
    installed on the system. If you don't have it installed, you 
    can still use the other options. xdotool can be installed via
    sudo apt-get install xdotool.


optional arguments:
  -h, --help            show this help message and exit
  -w, --window          spawns new window
  -t, --tab             spawns new tab
  -m, --minimize        minimizes current window
  -M, --maximize        maximizes window
  -u, --unmaximize      unmaximizes window
  -v VIEWPORT, --viewport VIEWPORT
                        send window to workspace number
  -r, --right           send window to workspace right
  -d, --down            send window to workspace down

Kod źródłowy skryptu:

Skrypt źródłowy jest dostępny na GitHub, jak również tutaj. Najnowsze zmiany prawdopodobnie trafią do GitHub, a nie tutaj, więc zdecydowanie sugeruję sprawdzenie tam najnowszej wersji. Sugeruje się również zamieszczanie tam raportów o błędach.

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Program name: windowctrl.py
Author: Sergiy Kolodyazhnyy
Date:  Sept 18, 2016
Written for: http://askubuntu.com/q/826310/295286
Tested on Ubuntu 16.04 LTS
"""
from __future__ import print_function
import gi
gi.require_version('Gdk', '3.0')
from gi.repository import Gio,Gdk
import sys
import dbus
import subprocess
import argparse

def gsettings_get(schema,path,key):
    """Get value of gsettings schema"""
    if path is None:
        gsettings = Gio.Settings.new(schema)
    else:
        gsettings = Gio.Settings.new_with_path(schema,path)
    return gsettings.get_value(key)

def run_cmd(cmdlist):
    """ Reusable function for running shell commands"""
    try:
        stdout = subprocess.check_output(cmdlist)
    except subprocess.CalledProcessError:
        print(">>> subprocess:",cmdlist)
        sys.exit(1)
    else:
        if stdout:
            return stdout

def get_dbus(bus_type,obj,path,interface,method,arg):
    # Reusable function for accessing dbus
    # This basically works the same as 
    # dbus-send or qdbus. Just give it
    # all the info, and it will spit out output
    if bus_type == "session":
        bus = dbus.SessionBus() 
    if bus_type == "system":
        bus = dbus.SystemBus()
    proxy = bus.get_object(obj,path)
    method = proxy.get_dbus_method(method,interface)
    if arg:
        return method(arg)
    else:
        return method() 

def new_window():
    screen = Gdk.Screen.get_default()
    active_xid = int(screen.get_active_window().get_xid())
    app_path = get_dbus( 'session',
                         'org.ayatana.bamf',
                         '/org/ayatana/bamf/matcher',
                         'org.ayatana.bamf.matcher',
                         'ApplicationForXid',
                         active_xid
                         )

    desk_file  = get_dbus('session',
                          'org.ayatana.bamf',
                          str(app_path),
                          'org.ayatana.bamf.application',
                          'DesktopFile',
                          None
                          )

    # Big credit to Six: http://askubuntu.com/a/664272/295286
    Gio.DesktopAppInfo.new_from_filename(desk_file).launch_uris(None)



def enumerate_viewports():
    """ generates enumerated dictionary of viewports and their
        indexes, counting left to right """
    schema="org.compiz.core"
    path="/org/compiz/profiles/unity/plugins/core/"
    keys=['hsize','vsize']
    screen = Gdk.Screen.get_default()
    screen_size=[ screen.get_width(),screen.get_height()]
    grid=[ int(str(gsettings_get(schema,path,key))) for key in keys]
    x_vals=[ screen_size[0]*x for x in range(0,grid[0]) ]
    y_vals=[screen_size[1]*x for x in range(0,grid[1]) ]

    viewports=[(x,y)  for y in y_vals for x in x_vals ]

    return {vp:ix for ix,vp in enumerate(viewports,1)}


def get_current_viewport():
    """returns tuple representing current viewport, 
       in format (width,height)"""
    vp_string = run_cmd(['xprop', '-root', 
                         '-notype', '_NET_DESKTOP_VIEWPORT'])
    vp_list=vp_string.decode().strip().split('=')[1].split(',')
    return tuple( int(i)  for i in vp_list )

def maximize():

    screen = Gdk.Screen.get_default()
    window = screen.get_active_window()
    window.maximize()
    screen.get_active_window()
    window.process_all_updates()

def unmaximize():

    screen = Gdk.Screen.get_default()
    window = screen.get_active_window()
    window.unmaximize()
    screen.get_active_window()
    window.process_all_updates()

def minimize():

    screen = Gdk.Screen.get_default()
    window = screen.get_active_window()
    window.iconify()
    window.process_all_updates()

def window_move(viewport):

    # 1. grab window object
    # 2. jump viewport 0 0 so we can move only
    #    in positive plane
    # 3. move the window.
    # 4. set viewport back to what it was

    # Step 1
    screen = Gdk.Screen.get_default()
    screen_size=[ screen.get_width(),screen.get_height()]
    window = screen.get_active_window()

    viewports = enumerate_viewports()
    current = get_current_viewport()
    current_num = viewports[current]
    destination = [ 
                   key for  key,val in viewports.items() 
                   if val == int(viewport)
                   ][0]
    # Step 2.
    run_cmd([
            'xdotool',
            'set_desktop_viewport',
            '0','0'
            ]) 
    # Step 3.
    window.move(destination[0],destination[1])
    window.process_all_updates()

    run_cmd([
            'xdotool',
            'set_desktop_viewport',
            str(current[0]),
            str(current[1])
            ]) 

def move_right():
    sc = Gdk.Screen.get_default()
    width = sc.get_width()
    win = sc.get_active_window()
    pos = win.get_origin()
    win.move(width,pos.y)
    win.process_all_updates()

def move_down():
    sc = Gdk.Screen.get_default()
    height = sc.get_height()
    win = sc.get_active_window()
    pos = win.get_origin()
    win.move(pos.x,height)
    win.process_all_updates()

def new_tab():
    run_cmd(['xdotool','key','ctrl+shift+t'])

def parse_args():
    """ Parse command line arguments"""

    info="""Copyright 2016. Sergiy Kolodyazhnyy.

    Window control for terminal emulators. Originally written
    for gnome-terminal under Ubuntu with Unity desktop but can 
    be used with any other terminal emulator that conforms to 
    gnome-terminal keybindings. It can potentially be used for 
    controlling other windows as well via binding this script
    to a keyboard shortcut.

    Note that --viewport and --tab options require xdotool to be
    installed on the system. If you don't have it installed, you 
    can still use the other options. xdotool can be installed via
    sudo apt-get install xdotool.
    """
    arg_parser = argparse.ArgumentParser(
                 description=info,
                 formatter_class=argparse.RawTextHelpFormatter)
    arg_parser.add_argument(
                '-w','--window', action='store_true',
                help='spawns new window',
                required=False)
    arg_parser.add_argument(
                '-t','--tab',action='store_true',
                help='spawns new tab',
                required=False)
    arg_parser.add_argument(
                '-m','--minimize',action='store_true',
                help='minimizes current window',
                required=False)
    arg_parser.add_argument(
                '-M','--maximize',action='store_true',
                help='maximizes window',
                required=False)
    arg_parser.add_argument(
                '-u','--unmaximize',action='store_true',
                help='unmaximizes window',
                required=False)
    arg_parser.add_argument(
               '-v','--viewport',action='store',
               type=int, help='send window to workspace number',
               required=False)
    arg_parser.add_argument(
               '-r','--right',action='store_true',
               help='send window to workspace right',
               required=False)
    arg_parser.add_argument(
               '-d','--down',action='store_true',
               help='send window to workspace down',
               required=False)
    return arg_parser.parse_args()

def main():

    args = parse_args()

    if args.window:
       new_window()
    if args.tab:
       new_tab()
    if args.down:
       move_down()
    if args.right:
       move_right()       
    if args.viewport:
       window_move(args.viewport)
    if args.minimize:
       minimize()
    if args.maximize:
       maximize()
    if args.unmaximize:
       unmaximize()

if __name__ == '__main__':
    main()

Notatki dodatkowe

  • Zapytałeś „Czy w Gnome-Terminal jest jakieś polecenie lub jakaś powłoka z kartami do otwarcia nowej karty?” Instrukcja Gnome Terminal nie zawiera takiej opcji. Powłoki to narzędzia wiersza polecenia. Karty są funkcją aplikacji GUI. Istnieją multipleksery końcowe, takie jak screenlub, tmuxktóre mogą mieć „tabulatory” lub podzielone okna, które są zbliżone do „powłoki z kartami”, ale nie jest to ten sam typ zachowania, o który pytasz. Zasadniczo odpowiedź na twoje pytanie brzmi „nie”. Zawsze są alternatywy, a moja odpowiedź zawiera jedną z nich. Traktuje okno terminala zgodnie ze swoją naturą - okno GUI X11.

  • Jak ta odpowiedź odnosi się do aliasów? Cóż, przede wszystkim aliasy mogą być nieco nieporządne, szczególnie jeśli chodzi o cytowanie i analizowanie wielu danych wyjściowych z wielu poleceń. Ten skrypt daje jedno, scentralizowane polecenie z flagami / przełącznikami do wykonania dyskretnego zadania na oknie. Ułatwia to także aliasy. Można to zrobić alias nw='windowctrl.py --window'. O wiele krótszy, o wiele ładniejszy.

Sergiy Kolodyazhnyy
źródło
Cieszę się z podzielonych terminali
Akiva,
1
@Akiva, czy chcesz, żebym powiązał pytanie dotyczące podziału terminala? tak przy okazji, próbowałeś tego skryptu? co myślisz ?
Sergiy Kolodyazhnyy
Spróbuję twojego skryptu, ponieważ powyższa odpowiedź sprawia mi kłopot. Jednak mogę nie mieć tyle szczęścia, ponieważ problem dotyczy głównie xdotool.
Akiva
@Akiva i z czym jest problem xdotool? Może mógłbym to naprawić?
Sergiy Kolodyazhnyy
W tej sprawie będę musiał się z tobą skontaktować. Być może mam do czynienia z niestandardowym układem klawiatury lub faktem, że mam 16.10 lub że próbuję na guake.
Akiva