Skip to content

Latest commit

 

History

History
144 lines (112 loc) · 4.64 KB

README.zh_CN.md

File metadata and controls

144 lines (112 loc) · 4.64 KB

gnome终端实现选中复制和右键粘贴功能

基于个人测试,该方法适用于 gnome-terminal 版本 3.36 到 3.44。

0x01. 获取 gnome 终端源码

sudo apt-get update
apt-get source gnome-terminal

0x02. 安装 GNOME 开发环境

sudo apt-get build-dep gnome-terminal

如果缺失第三方库,请手动安装。

唯一需要修改的文件是 gnome-terminal-3.44.0/src/terminal-screen.c(我所使用的 GNOME 终端版本)。

0x03. 定义事件函数

在按压事件后增加释放事件。

static gboolean terminal_screen_popup_menu (GtkWidget *widget);
static gboolean terminal_screen_button_press (GtkWidget *widget,
                                              GdkEventButton *event);
// 增加按压释放事件
static gboolean terminal_screen_button_release (GtkWidget *widget,
                                              GdkEventButton *event);
static void terminal_screen_hierarchy_changed (GtkWidget *widget,
                                               GtkWidget *previous_toplevel);

0x04. 绑定按压释放事件的执行函数

在函数 static void terminal_screen_class_init (TerminalScreenClass *klass) 中添加 widget_class->button_release_event = terminal_screen_button_release;

terminal_screen_class_init (TerminalScreenClass *klass)
{
  GObjectClass *object_class = G_OBJECT_CLASS (klass);
  GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass);
  VteTerminalClass *terminal_class = VTE_TERMINAL_CLASS (klass);
  GSettings *settings;

  object_class->constructed = terminal_screen_constructed;
  object_class->dispose = terminal_screen_dispose;
  object_class->finalize = terminal_screen_finalize;
  object_class->get_property = terminal_screen_get_property;
  object_class->set_property = terminal_screen_set_property;

  widget_class->realize = terminal_screen_realize;
  widget_class->style_updated = terminal_screen_style_updated;
  widget_class->drag_data_received = terminal_screen_drag_data_received;
  widget_class->button_press_event = terminal_screen_button_press;
// 绑定按压释放事件的执行函数
  widget_class->button_release_event = terminal_screen_button_release;
  widget_class->popup_menu = terminal_screen_popup_menu;
  widget_class->hierarchy_changed = terminal_screen_hierarchy_changed;
  terminal_class->child_exited = terminal_screen_child_exited;

0x05. 修改右键事件的执行函数逻辑

static gboolean
terminal_screen_button_press (GtkWidget      *widget,
                              GdkEventButton *event)
{
  // ... 代码略

  if (event->type == GDK_BUTTON_PRESS && event->button == 3)
    {
      if (!(event->state & (GDK_SHIFT_MASK | GDK_CONTROL_MASK | GDK_MOD1_MASK)))
        {
          /* on right-click, we should first try to send the mouse event to
           * the client, and popup only if that's not handled. */
          //if (button_press_event && button_press_event (widget, event))
            //return TRUE;
 
          //terminal_screen_do_popup (screen, event, hyperlink, url, url_flavor, number_info);
          // 注释上面的三行代码,直接跳过跳出右键菜单
          //并增加下面vte的代码调用(在3.44版本)
          vte_terminal_paste_clipboard (VTE_TERMINAL (screen));
          
          hyperlink = nullptr; /* adopted to the popup info */
          url = nullptr; /* ditto */
          number_info = nullptr; /* ditto */
          timestamp_info = nullptr; /* ditto */
          return TRUE;
        }
      else if (!(event->state & (GDK_CONTROL_MASK | GDK_MOD1_MASK)))
        {
          // ... 代码略
        }
    }

0x06. 实现选中复制函数

static gboolean
terminal_screen_button_release (GtkWidget *widget,
                                GdkEventButton *event){
    gboolean ret;
 
    TerminalScreen *screen = TERMINAL_SCREEN (widget);
    gboolean (* button_release_event) (GtkWidget*, GdkEventButton*) =
            GTK_WIDGET_CLASS (terminal_screen_parent_class)->button_release_event;
    ret = FALSE;
    if (button_release_event){
        ret = button_release_event (widget, event);
    }
 
    if (event->button == 1){
        gboolean can_copy;
        can_copy = vte_terminal_get_has_selection (VTE_TERMINAL (screen));
 
        if (can_copy)
            vte_terminal_copy_clipboard (VTE_TERMINAL (screen));
    }
 
    return ret;
}

0x07. 编译和安装

在源代码中进行必要的更改后,进入 gnome-terminal-3.44.0 目录并执行:

dpkg-buildpackage -us -uc -b

安装:

sudo dpkg -i gnome-terminal_3.44.0-1ubuntu1_amd64.deb

重新启动终端,你将能够使用终端选中复制和右键粘贴功能。