Có một lệnh trong Gnome-Terminal hoặc bất kỳ shell có thể tab nào để mở một tab mới không?


11

Tôi không tìm kiếm một phím tắt, thay vào đó tôi muốn có một lệnh cho:

  • Cửa sổ mới
  • Tab mới
  • Đóng tab hoặc cửa sổ hiện tại
  • Tối đa hóa cửa sổ Shell
  • Thu nhỏ cửa sổ Shell
  • Di chuyển Shell đến một không gian làm việc khác
  • Chuyển đổi tab

Và về cơ bản bất cứ điều gì như thế này. Nhớ lại; Tôi không muốn các phím tắt, nhưng các lệnh thực tế. Lý do cho điều này là vì vậy tôi có thể sử dụng chức năng bí danh.


1
Con trăn có ổn với bạn không?
Sergiy Kolodyazhnyy

4
"Đóng tab hiện tại" - lệnh này được gọi là "exit": D
egmont

"Tôi không muốn các phím tắt [...] vì vậy tôi có thể sử dụng chức năng bí danh" - bạn có thể giải thích rõ hơn về điều này không? Lợi thế chính xác mà bạn hy vọng thay vì các phím tắt nổi tiếng là gì? Vấn đề hoặc thiếu chức năng trong các phím tắt là gì? Tôi nghĩ rằng họ là phương pháp phù hợp cho những gì bạn đang tìm kiếm.
egmont

@egmont Tôi là một Vim Addict, nếu điều đó có ý nghĩa.
Akiva

Vì vậy, giả sử, ví dụ: Tối đa hóa, thay vì có một phím nóng quản lý cửa sổ hoạt động cho tất cả các loại cửa sổ (trình duyệt, trình chỉnh sửa hình ảnh, trình xử lý văn bản, v.v.) ở tất cả các trạng thái (ví dụ như bất cứ điều gì bạn đang làm trong chúng), bạn ' d thích có một lệnh chỉ hoạt động cho thiết bị đầu cuối và không có ứng dụng nào khác, và chỉ khi nó không chạy bất kỳ lệnh nào bên trong (tất nhiên không phải là vỏ mặc định). Không, xin lỗi, ý tưởng này vẫn không quá có ý nghĩa với tôi :(
egmont

Câu trả lời:


14

Bạn không thể làm điều này theo mặc định trong Gnome-Terminal, ít nhất là với các lệnh thô.

Tuy nhiên, bạn có thể viết các tập lệnh gọi các phím tắt có thể làm điều này. Lưu ý rằng bạn cần xdotoolcho việc này:sudo apt install xdotool

  • Cửa sổ mới : Khởi chạy một cửa sổ đầu cuối mới với nw
    Chúng tôi có thể làm điều này chỉ với gnome-terminal.
    Thêm vào.bashrc :

    echo "alias nw=gnome-terminal" >> ~/.bashrc
  • Tab mới : Khởi chạy một tab mới với nt
    Chúng tôi có thể làm điều này với xdotool getactivewindow $(xdotool key ctrl+shift+t)
    Thêm vào.bashrc :

    echo "alias nt='xdotool getactivewindow $(xdotool key ctrl+shift+t)'" >> .bashrc
  • Đóng tab : Đóng tab hiện tại hoặc cửa sổ bằng ct
    xdotoolcác lần đình công: xdotool getactivewindow $(xdotool key ctrl+shift+w)
    Thêm vào.bashrc :

    echo "alias ct='xdotool getactivewindow $(xdotool key ctrl+shift+w)'" >> .bashrc
  • Tối đa hóa cửa sổ : Tối đa hóa toàn bộ cửa sổ với maw
    Chúng tôi có thể sử dụng wmctrltại đây: wmctrl -r :ACTIVE: -b toggle,maximized_vert,maximized_horz
    Thêm vào.bashrc :

    echo "alias maw='wmctrl -r :ACTIVE: -b toggle,maximized_vert,maximized_horz'" >> .bashrc
  • Thu nhỏ cửa sổ : Thu nhỏ toàn bộ cửa sổ bằng miw
    Chúng tôi có thể sử dụng xdotoollại: xdotool windowminimize $(xdotool getactivewindow)
    Thêm vào.bashrc :

    echo "alias miw='xdotool windowminimize $(xdotool getactivewindow)'" >> .bashrc
  • Di chuyển đến Không gian làm việc : Di chuyển một cửa sổ sang một không gian làm việc khác với mtw <id>
    Điều này hầu như không thể thực hiện được trong kịch bản shell và vượt xa trải nghiệm cá nhân của tôi. Tôi sẽ khuyên bạn nên sử dụng kịch bản của Serg cho mục đích này, vì nó thực sự hoạt động như bây giờ. Ah, lợi ích của Compiz.


7

Giới thiệu

Kịch bản được trình bày trong câu trả lời này cho phép người dùng điều khiển cửa sổ đầu cuối của họ thông qua một lệnh và danh sách các tùy chọn. Nó rất đơn giản để sử dụng và tương thích với bất kỳ trình giả lập thiết bị đầu cuối nào có các phím bấm tương tự gnome-terminal. Tùy chọn di chuyển cũng có thể được sử dụng với các thiết bị đầu cuối khác, nhưng việc mở tab không được đảm bảo cho các thiết bị đầu cuối đó.

Kịch bản bao gồm mở tab, mở cửa sổ, di chuyển xuống không gian làm việc, bên phải không gian làm việc, không gian làm việc cụ thể được tham chiếu theo số nguyên, thu nhỏ, tối đa hóa và tối đa hóa cửa sổ. Điều duy nhất mà tập lệnh không bao gồm là đóng tab / cửa sổ đơn giản vì mỗi trình giả lập shell / terminal đã có một lệnh cho nó - exithoặc thay thế thông qua CtrlDphím tắt.

!!! LƯU Ý: bạn sẽ cần xdotoolchuyển đổi không gian làm việc và mở tab. Cài đặt nó qua sudo apt-get install xdotool. Nếu bạn không muốn cài đặt các gói bổ sung, hãy nhớ rằng không gian làm việc và chuyển đổi tab sẽ không hoạt động , nhưng các tùy chọn khác sẽ.

Sử dụng:

Tất cả các đối số windowctrl.pylà tùy chọn, vì vậy chúng có thể được sử dụng riêng rẽ hoặc có khả năng cùng nhau. Như thể hiện bởi -htùy chọ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

Mã nguồn script:

Mã nguồn tập lệnh có sẵn trên GitHub cũng như tại đây. Những thay đổi mới nhất có khả năng đi vào GitHub chứ không phải ở đây, vì vậy tôi khuyên bạn nên kiểm tra phiên bản mới nhất ở đó. Nó cũng được đề xuất để gửi báo cáo lỗi ở đó là tốt.

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

Ghi chú bên

  • Bạn đã hỏi "Có lệnh nào trong Gnome-Terminal hoặc bất kỳ vỏ có thể gắn thẻ nào để mở tab mới không?" Hướng dẫn sử dụng Gnome Terminal không liệt kê tùy chọn như vậy. Các shell là các tiện ích dòng lệnh. Tab là tính năng của các ứng dụng GUI. Có các bộ ghép kênh đầu cuối như screenhoặc tmuxcó thể có "tab" hoặc cửa sổ phân chia, loại này gần với "vỏ bảng" nhưng đây không phải là loại hành vi bạn yêu cầu. Về cơ bản, trả lời câu hỏi của bạn là "Không". Luôn có những lựa chọn thay thế, và câu trả lời của tôi cung cấp một trong số chúng. Nó xử lý cửa sổ đầu cuối theo tính chất của nó - cửa sổ GUI X11.

  • Làm thế nào để câu trả lời này liên quan đến bí danh? Vâng, trước hết các bí danh có thể hơi lộn xộn, đặc biệt là khi trích dẫn và phân tích nhiều kết quả đầu ra từ nhiều lệnh. Kịch bản lệnh này cung cấp cho bạn một lệnh tập trung, với cờ / công tắc để thực hiện một tác vụ riêng biệt trên một cửa sổ. Nó cũng làm cho bí danh đơn giản hơn. Bạn có thể làm alias nw='windowctrl.py --window'. Ngắn hơn nhiều, gọn gàng hơn nhiều.


Tôi hài lòng với thiết bị đầu cuối phân chia
Akiva

1
@Akiva bạn có muốn tôi liên kết một câu hỏi liên quan đến việc tách thiết bị đầu cuối không? Bạn đã thử kịch bản này chưa? bạn nghĩ sao ?
Sergiy Kolodyazhnyy

Tôi sẽ thử kịch bản của bạn, bởi vì câu trả lời ở trên đang gây rắc rối cho tôi. Tuy nhiên tôi có thể không có quá nhiều may mắn, do vấn đề chủ yếu là với xdotool.
Akiva

@Akiva và vấn đề là xdotoolgì? Có lẽ tôi có thể sửa nó?
Sergiy Kolodyazhnyy

Tôi sẽ phải lấy lại cho bạn về điều đó. Tôi có thể phải làm với bố cục bàn phím tùy chỉnh của mình, hoặc thực tế là tôi vào ngày 16.10, hoặc tôi đang thử nó trên guake.
Akiva
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.