Gnome终端中是否有命令,或者任何可打开标签的外壳程序中都有打开新标签页的命令?


11

我不是在寻找键盘快捷键,而是想要以下命令:

  • 新窗户
  • 新标签
  • 关闭当前标签页或窗口
  • 最大化外壳窗口
  • 最小化外壳窗口
  • 将Shell移到其他工作空间
  • 切换标签

基本上像这样。记得; 我不想要快捷方式,而是想要实际的命令。这样做的原因是我可以利用别名功能。


1
python可以吗?
Sergiy Kolodyazhnyy

4
“关闭当前标签” –此命令称为“退出”:D
egmont

“我不希望使用快捷方式,以便可以使用别名功能” –您能否详细说明一下?您希望代替众所周知的快捷方式的确切优势是什么?快捷方式有什么问题或缺少功能?我认为它们是您要寻找的正确方法。
egmont

@egmont如果有任何道理,我是Vim迷。
Akiva

因此,比方说,例如对于最大化,而不是拥有一个在所有状态(即您在其中所做的任何工作)都适用于所有类型的窗口(浏览器,图像编辑器,文字处理器等)的窗口管理器热键, d希望有一个仅适用于终端而不适用于其他应用程序的命令,并且前提是该命令未在内部运行任何命令(当然是默认外壳程序除外)。不,对不起,这个主意对我来说仍然没有太大意义:(
例如,monte

Answers:


14

默认情况下,至少在原始命令中,您不能在Gnome终端中执行此操作。

但是,您可以编写脚本来调用可以执行此操作的键盘快捷键。请注意,您需xdotool要这样做:sudo apt install xdotool

  • 新窗口:启动一个新的终端窗口,nw
    我们可以做到这一点只gnome-terminal
    添加到.bashrc

    echo "alias nw=gnome-terminal" >> ~/.bashrc
  • 新建标签:使用nt
    可以启动新标签,我们可以通过xdotool getactivewindow $(xdotool key ctrl+shift+t)
    添加到.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
  • 移动到工作区:使用shell 将窗口移动到另一个工作区在shell脚本中几乎是不可能的,mtw <id>
    这超出了我的个人经验。我建议为此使用Serg的脚本,因为到目前为止它实际上已经可以工作了。啊,Compiz的好处。


7

介绍

此答案中显示的脚本允许用户通过一个命令和选项列表来控制其终端窗口。它易于使用,并且与具有类似于的键绑定的任何终端仿真器兼容gnome-terminal。移动选项也可以与其他终端一起使用,但是不能保证这些终端的凸舌打开。

该脚本涵盖了打开选项卡,打开窗口,向下移动到工作空间,向右移动工作空间,以整数表示的特定工作空间,最小化,最大化和非最大化窗口。该脚本唯一无法涵盖的就是仅由于每个外壳程序/终端仿真器已经有一个命令(exit或通过CtrlD快捷方式)来关闭选项卡/窗口。

!!! 注意:您将需要xdotool切换工作区和打开选项卡。通过安装sudo apt-get install xdotool。如果您不想安装额外的软件包,请记住工作空间和选项卡切换将不起作用,但其他选项将起作用

用法:

所有to的参数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终端中是否有命令,或者有任何可打开标签的外壳程序打开了新标签页?” Gnome Terminal手册未列出此类选项。外壳程序是命令行实用程序。选项卡是GUI应用程序的功能。有一些终端多路复用器,例如screentmux可以具有“选项卡”或拆分窗口,其类型接近于“可标签外壳”,但这与您要求的行为类型不同。基本上,您的问题的答案是“否”。总有其他选择,我的回答提供了其中一种。它根据其性质来处理终端窗口-X11 GUI窗口。

  • 这个答案与别名有什么关系?好吧,首先,别名可能会有些混乱,尤其是在引用和解析来自多个命令的多个输出时。该脚本为您提供了一个集中的命令,带有标志/开关,可以在窗口上执行离散任务。这也使别名更简单。你可以做的alias nw='windowctrl.py --window'。更短,更整洁。


我对分割终端感到满意
Akiva

1
@Akiva是否要我链接与拆分终端有关的问题?您是否尝试过此脚本?你怎么看 ?
Sergiy Kolodyazhnyy

我将尝试您的脚本,因为上面的答案给我带来了麻烦。但是,由于问题主要出在xdotool上,所以我可能没有那么幸运。
Akiva

@Akiva是什么问题xdotool?也许我可以解决?
Sergiy Kolodyazhnyy

我得就此与您联系。我可能与我的自定义键盘布局有关,或者与我使用16.10或在guake上尝试有关。
Akiva
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.