มีคำสั่งใน Gnome-Terminal หรือเชลล์ tabbable ใด ๆ เพื่อเปิดแท็บใหม่หรือไม่?


11

ฉันไม่ได้มองหาแป้นพิมพ์ลัด แต่ฉันต้องการคำสั่ง:

  • หน้าต่างใหม่
  • แท็บใหม่
  • ปิดแท็บหรือหน้าต่างปัจจุบัน
  • ขยายหน้าต่างเชลล์ให้ใหญ่สุด
  • ย่อขนาดหน้าต่างเชลล์
  • ย้ายเชลล์ไปยังพื้นที่ทำงานอื่น
  • สลับแท็บ

และโดยทั่วไปอะไรเช่นนี้ โปรดจำไว้ว่า; ฉันไม่ต้องการทางลัด แต่เป็นคำสั่งจริง เหตุผลของเรื่องนี้คือเพื่อให้ฉันสามารถใช้ฟังก์ชั่นนามแฝง


1
หลามตกลงกับคุณหรือไม่
Sergiy Kolodyazhnyy

4
"ปิดแท็บปัจจุบัน" - คำสั่งนี้เรียกว่า "exit": D
egmont

"ฉันไม่ต้องการทางลัด [... ] เพื่อให้ฉันสามารถใช้ฟังก์ชันการทำงานของชื่อแทน" - คุณช่วยอธิบายเรื่องนี้ให้ละเอียดหน่อยได้ไหม? อะไรคือข้อได้เปรียบที่คุณคาดหวังแทนที่จะเป็นทางลัดที่รู้จักกันดี ปัญหาหรือการทำงานที่ขาดหายไปในทางลัดคืออะไร ฉันคิดว่าพวกเขาเป็นแนวทางที่ถูกต้องสำหรับสิ่งที่คุณกำลังมองหา
egmont

@egmont ฉันเป็นกลุ่มติดยาเสพติดถ้านั่นทำให้รู้สึกใด ๆ
Akiva

ดังนั้นสมมติเช่นสำหรับขยายใหญ่สุดแทนการมีฮอตคีย์ตัวจัดการหน้าต่างซึ่งทำงานได้กับหน้าต่างทุกชนิด (เบราว์เซอร์โปรแกรมแก้ไขรูปภาพโปรแกรมประมวลผลคำ ฯลฯ ) ในทุกสถานะ (เช่นสิ่งที่คุณทำภายใน) ต้องการที่จะมีคำสั่งที่ใช้งานได้กับเทอร์มินัลเท่านั้นและไม่มีแอพอื่นและถ้ามันไม่ได้รันคำสั่งใด ๆ ภายใน (นอกเหนือจากเชลล์เริ่มต้นแน่นอน) ไม่ขออภัยความคิดนี้ยังไม่สมเหตุสมผลสำหรับฉัน :(
egmont

คำตอบ:


14

คุณไม่สามารถทำสิ่งนี้ได้โดยค่าเริ่มต้นใน Gnome-Terminal อย่างน้อยก็มีคำสั่ง raw

อย่างไรก็ตามคุณสามารถเขียนสคริปต์ที่เรียกใช้แป้นพิมพ์ลัดที่สามารถทำได้ โปรดทราบว่าคุณต้องการxdotoolสิ่งนี้:sudo apt install xdotool

  • หน้าต่างใหม่ : เปิดตัวสถานีหน้าต่างใหม่ที่มีเราสามารถทำเช่นนี้มีเพียงnw
    เพิ่มไปที่ :gnome-terminal
    .bashrc

    echo "alias nw=gnome-terminal" >> ~/.bashrc
  • แท็บใหม่ : เปิดแท็บใหม่ด้วยnt
    เราสามารถทำได้ด้วยxdotool getactivewindow $(xdotool key ctrl+shift+t)
    Add to.bashrc :

    echo "alias nt='xdotool getactivewindow $(xdotool key ctrl+shift+t)'" >> .bashrc
  • ปิดแท็บ : ปิดแท็บหรือหน้าต่างปัจจุบันด้วยการct
    xdotoolโจมตีอีกครั้ง: xdotool getactivewindow $(xdotool key ctrl+shift+w)
    เพิ่มไปที่.bashrc :

    echo "alias ct='xdotool getactivewindow $(xdotool key ctrl+shift+w)'" >> .bashrc
  • หน้าต่างขยายใหญ่สุด : ขยายหน้าต่างให้ใหญ่สุดด้วยmaw
    เราสามารถใช้wmctrlที่นี่: wmctrl -r :ACTIVE: -b toggle,maximized_vert,maximized_horz
    เพิ่มไปที่.bashrc :

    echo "alias maw='wmctrl -r :ACTIVE: -b toggle,maximized_vert,maximized_horz'" >> .bashrc
  • ย่อเล็กสุดหน้าต่าง : ย่อเล็กสุดทั้งหน้าต่างด้วยmiw
    เราสามารถใช้xdotoolอีกครั้ง: xdotool windowminimize $(xdotool getactivewindow)
    เพิ่มไปที่.bashrc :

    echo "alias miw='xdotool windowminimize $(xdotool getactivewindow)'" >> .bashrc
  • ย้ายไปที่เวิร์กสเปซ: ย้ายหน้าต่างไปที่เวิร์กสเปซอื่นด้วยmtw <id>
    นี่จะแทบเป็นไปไม่ได้ในการเขียนสคริปต์เชลล์และเป็นวิธีที่เกินกว่าประสบการณ์ส่วนตัวของฉัน ฉันอยากจะแนะนำให้ใช้สคริปต์ของ Serg เพื่อจุดประสงค์นี้เพราะมันใช้งานได้จริงในตอนนี้ อาประโยชน์ของ Compiz


7

บทนำ

สคริปต์ที่แสดงในคำตอบนี้อนุญาตให้ผู้ใช้ควบคุมหน้าต่างเทอร์มินัลผ่านคำสั่งเดียวและรายการตัวเลือก มันเป็นเรื่องง่ายที่จะใช้และเข้ากันได้กับจำลอง terminal ใด ๆ ที่มี keybindings gnome-terminalคล้ายกับ ตัวเลือกการเคลื่อนย้ายสามารถใช้กับเทอร์มินัลอื่นเช่นกัน แต่การเปิดแท็บไม่ได้รับประกันสำหรับเทอร์มินัลเหล่านั้น

สคริปต์ครอบคลุมถึงการเปิดแท็บ, การเปิดหน้าต่าง, ย้ายไปที่เวิร์กสเปซลง, เวิร์กสเปซขวา, เวิร์กสเปซเฉพาะที่อ้างอิงโดยหมายเลขจำนวนเต็ม, การย่อ, การขยายให้ใหญ่สุดและ unmaximizing หน้าต่าง สิ่งเดียวที่สคริปต์ไม่ครอบคลุมคือการปิดแท็บ / หน้าต่างเพียงเพราะเชลล์ / เทอร์มินัลอีมูเลเตอร์มีคำสั่งอยู่แล้ว - exitหรืออีกวิธีหนึ่งผ่านCtrlDทางลัด

!!! หมายเหตุ: คุณจะต้องxdotoolสลับพื้นที่ทำงานและเปิดแท็บ sudo apt-get install xdotoolติดตั้งผ่านทาง หากคุณไม่ต้องการติดตั้งแพ็กเกจพิเศษโปรดจำไว้ว่าพื้นที่ทำงานและการสลับแท็บจะไม่ทำงานแต่ตัวเลือกอื่น ๆ

การใช้งาน:

อาร์กิวเมนต์ทั้งหมดที่windowctrl.pyเป็นทางเลือกดังนั้นจึงสามารถใช้แยกกันหรืออาจรวมเข้าด้วยกัน ตามที่แสดงโดย-hตัวเลือก

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

รหัสที่มาสคริปต์:

ซอร์สโค้ดสคริปต์นั้นมีอยู่ใน GitHub เช่นเดียวกับที่นี่ การเปลี่ยนแปลงล่าสุดมีแนวโน้มที่จะเข้าสู่ GitHub มากกว่าที่นี่ดังนั้นฉันขอแนะนำให้ตรวจสอบรุ่นล่าสุดที่นั่น นอกจากนี้ยังแนะนำให้โพสต์รายงานข้อผิดพลาดเช่นกัน

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

หมายเหตุด้านข้าง

  • คุณถาม "มีคำสั่งใน Gnome-Terminal หรือแท็บเชลล์ใด ๆ ที่สามารถเปิดแท็บใหม่ได้หรือไม่" คู่มือ Gnome Terminal ไม่ได้แสดงรายการตัวเลือกดังกล่าว เชลล์เป็นโปรแกรมอรรถประโยชน์บรรทัดคำสั่ง แท็บเป็นคุณสมบัติของแอปพลิเคชัน GUI มีเทอร์มินัลมัลติเพล็กเซอร์เช่นscreenหรือtmuxที่สามารถมี "แท็บ" หรือแยก windows ซึ่งเรียงลำดับของมาใกล้กับ "เชลล์ tabbable" แต่นี่ไม่ใช่พฤติกรรมที่คุณถาม โดยทั่วไปคำตอบสำหรับคำถามของคุณคือ "ไม่" มีทางเลือกอยู่เสมอและคำตอบของฉันให้หนึ่งในนั้น มันปฏิบัติต่อหน้าต่างเทอร์มินัลตามลักษณะของมัน - หน้าต่าง X11 GUI

  • คำตอบนี้เกี่ยวข้องกับนามแฝงอย่างไร เอาล่ะนามแฝงทั้งหมดอาจยุ่งหน่อยโดยเฉพาะอย่างยิ่งเมื่อพูดถึงและการแยกวิเคราะห์เอาต์พุตหลายคำจากหลายคำสั่ง สคริปต์นี้ให้คำสั่งรวมศูนย์จากคุณด้วยธง / สวิตช์เพื่อทำงานแยกต่างหากบนหน้าต่าง นอกจากนี้ยังทำให้นามแฝงง่ายขึ้น alias nw='windowctrl.py --window'คุณสามารถทำ สั้นกว่าเยอะมาก


ฉันมีความสุขกับอาคารแยก
Akiva

1
@Akiva คุณต้องการให้ฉันเชื่อมโยงคำถามที่เกี่ยวข้องกับการแยกขั้ว? คุณได้ลองใช้สคริปต์นี้แล้วหรือยัง คุณคิดอย่างไร ?
Sergiy Kolodyazhnyy

ฉันจะลองใช้สคริปต์ของคุณเพราะคำตอบข้างต้นทำให้ฉันเดือดร้อน อย่างไรก็ตามฉันอาจไม่มีโชคมากเนื่องจากปัญหาส่วนใหญ่กับ xdotool
Akiva

@Akiva และมีปัญหาxdotoolอะไร? บางทีฉันสามารถแก้ไขได้หรือไม่
Sergiy Kolodyazhnyy

ฉันจะต้องกลับไปหาคุณในเรื่องนั้น ฉันอาจต้องใช้รูปแบบแป้นพิมพ์ที่กำหนดเองของฉันหรือความจริงที่ฉันกำลัง 16.10 หรือว่าฉันพยายามที่จะเดา
Akiva
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.