¿Hay un comando en Gnome-Terminal, o algún shell tabble para abrir una nueva pestaña?

11

No estoy buscando un atajo de teclado, más bien quiero un comando para:

  • Nueva ventana
  • Nueva pestaña
  • Cerrar pestaña o ventana actual
  • Maximizar ventana de shell
  • Minimizar ventana de shell
  • Mueva Shell a un espacio de trabajo diferente
  • Cambiar pestaña

Y básicamente algo como esto. Recuerda; No quiero atajos, sino comandos reales. La razón de esto es para que pueda utilizar la funcionalidad de alias.

Akiva
fuente
1
¿Python está bien contigo?
Sergiy Kolodyazhnyy
44
"Cerrar pestaña actual" - este comando se llama "salir": D
egmont
"No quiero accesos directos [...] para poder utilizar la funcionalidad de alias". ¿Podría explicarme esto? ¿Cuál es la ventaja exacta que espera en lugar de los atajos conocidos? ¿Cuál es el problema o la falta de funcionalidad en los accesos directos? Creo que son el enfoque correcto para lo que estás buscando.
egmont
@egmont Soy un adicto a Vim, si eso tiene sentido.
Akiva
Entonces, digamos, por ejemplo, para Maximizar, en lugar de tener una tecla de acceso directo del administrador de ventanas que funcione para todo tipo de ventanas (navegador, editor de imágenes, procesador de textos, etc.) en todos los estados (es decir, lo que sea que esté haciendo dentro de ellas), usted ' Prefiero tener un comando que solo funcione para el terminal y ninguna otra aplicación, y solo si no está ejecutando ningún comando dentro (aparte del shell predeterminado, por supuesto). No, lo siento, esta idea todavía no tiene mucho sentido para mí :(
egmont

Respuestas:

14

No puede hacer esto de forma predeterminada en Gnome-Terminal, al menos con comandos sin formato.

Sin embargo, puede escribir scripts que llamen atajos de teclado que puedan hacer esto. Tenga en cuenta que necesita xdotoolpara esto:sudo apt install xdotool

  • Nueva ventana : Inicie una nueva ventana de terminal con nw
    Podemos hacer esto con solo gnome-terminal.
    Añadir a.bashrc :

    echo "alias nw=gnome-terminal" >> ~/.bashrc
  • Nueva pestaña : Inicie una nueva pestaña con nt
    Podemos hacer esto con xdotool getactivewindow $(xdotool key ctrl+shift+t)
    Agregar a.bashrc :

    echo "alias nt='xdotool getactivewindow $(xdotool key ctrl+shift+t)'" >> .bashrc
  • Cerrar pestaña : cierre la pestaña o ventana actual con ct
    xdotoolhuelgas nuevamente: xdotool getactivewindow $(xdotool key ctrl+shift+w)
    Agregar a.bashrc :

    echo "alias ct='xdotool getactivewindow $(xdotool key ctrl+shift+w)'" >> .bashrc
  • Maximizar ventana : Maximice toda la ventana con maw
    Podemos usar wmctrlaquí: wmctrl -r :ACTIVE: -b toggle,maximized_vert,maximized_horz
    Agregar a.bashrc :

    echo "alias maw='wmctrl -r :ACTIVE: -b toggle,maximized_vert,maximized_horz'" >> .bashrc
  • Minimizar ventana : minimiza toda la ventana con miw
    Podemos usar xdotoolnuevamente: xdotool windowminimize $(xdotool getactivewindow)
    Agregar a.bashrc :

    echo "alias miw='xdotool windowminimize $(xdotool getactivewindow)'" >> .bashrc
  • Mover al espacio de trabajo : mover una ventana a otro espacio de trabajo con mtw <id>
    Esto sería apenas posible en scripts de shell y está más allá de mi experiencia personal. Recomendaría usar el script de Serg para este propósito, porque en realidad funciona a partir de ahora. Ah, los beneficios de Compiz.

Kaz Wolfe
fuente
7

Introducción

El script presentado en esta respuesta permite al usuario controlar su ventana de terminal mediante un solo comando y una lista de opciones. Es simple de usar y compatible con cualquier emulador de terminal que tenga combinaciones de teclas similares gnome-terminal. Las opciones de movimiento también se pueden usar con otros terminales, pero la apertura de pestañas no está garantizada para esos terminales.

La secuencia de comandos abarca la apertura de pestañas, la apertura de ventanas, el desplazamiento hacia abajo del espacio de trabajo, el espacio de trabajo hacia la derecha, el espacio de trabajo específico al que se hace referencia por número entero, minimizando, maximizando y sin maximizar una ventana. Lo único que no cubre el script es cerrar la pestaña / ventana simplemente porque cada emulador de shell / terminal ya tiene un comando para él, exito alternativamente a través de un CtrlDacceso directo.

!!! NOTA: necesitará xdotoolcambiar el espacio de trabajo y abrir pestañas. Instalarlo a través de sudo apt-get install xdotool. Si prefiere no instalar paquetes adicionales, tenga en cuenta que el espacio de trabajo y el cambio de tabulación no funcionarán , pero otras opciones sí.

Uso:

Todos los argumentos para windowctrl.pyson opcionales, por lo que se pueden usar por separado o potencialmente juntos. Como se muestra por -hopción.

$ ./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

Código fuente del script:

El código fuente del script está disponible en GitHub y aquí. Es probable que los últimos cambios entren en GitHub en lugar de aquí, por lo que le sugiero que compruebe la última versión allí. También se sugiere publicar informes de errores allí también.

#!/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()

Notas al margen

  • Usted preguntó "¿Hay un comando en Gnome-Terminal, o algún shell tabble para abrir una nueva pestaña?" El manual de Terminal de Gnome no enumera tal opción. Los shells son utilidades de línea de comandos. Las pestañas son características de las aplicaciones GUI. Hay multiplexores terminales como screeno tmuxque pueden tener "pestañas" o ventanas divididas, que se acerca al "shell tabulable", pero este no es el mismo tipo de comportamiento que usted pregunta. Básicamente, la respuesta a su pregunta es "No". Siempre hay alternativas, y mi respuesta proporciona una de ellas. Trata la ventana de terminal de acuerdo con su naturaleza: ventana X11 GUI.

  • ¿Cómo se relaciona esta respuesta con los alias? Bueno, en primer lugar, los alias pueden ser un poco confusos, especialmente cuando se trata de citar y analizar múltiples salidas de múltiples comandos. Este script le brinda un comando centralizado, con banderas / interruptores para hacer una tarea discreta en una ventana. También simplifica los alias. Usted podría hacer alias nw='windowctrl.py --window'. Mucho más corto, mucho más ordenado.

Sergiy Kolodyazhnyy
fuente
Estoy contento con las terminales divididas
Akiva
1
@ Akiva, ¿quieres que vincule una pregunta relacionada con la división de terminal? ¿Has probado este script por cierto? Qué piensas ?
Sergiy Kolodyazhnyy
Probaré tu guión, porque la respuesta anterior me está dando problemas. Sin embargo, es posible que no tenga tanta suerte, debido a que el problema es principalmente con xdotool.
Akiva
@Akiva y ¿cuál es el problema xdotool? Tal vez podría arreglarlo?
Sergiy Kolodyazhnyy
Tendré que contactarte con eso. Puede que tenga que ver con mi diseño de teclado personalizado, o el hecho de que estoy en 16.10, o que lo estoy probando en guake.
Akiva