Skip to content

Commit

Permalink
Add support for embedding terminal
Browse files Browse the repository at this point in the history
  • Loading branch information
kou committed Aug 21, 2021
1 parent 835548b commit 16f4ad0
Show file tree
Hide file tree
Showing 5 changed files with 123 additions and 7 deletions.
7 changes: 7 additions & 0 deletions lib/rabbit/action/toggle.rb
Original file line number Diff line number Diff line change
Expand Up @@ -71,5 +71,12 @@ def act_toggle_magnifier(action, group, canvas)
def act_toggle_magnifier_config(config, canvas)
config[:label] = N_("Magnifier")
end

def act_toggle_terminal(action, group, canvas)
canvas.toggle_terminal
end
def act_toggle_terminal_config(config, canvas)
config[:label] = N_("Terminal")
end
end
end
4 changes: 3 additions & 1 deletion lib/rabbit/canvas.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright (C) 2004-2019 Sutou Kouhei <kou@cozmixng.org>
# Copyright (C) 2004-2021 Sutou Kouhei <kou@cozmixng.org>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -43,6 +43,8 @@ class Canvas
def_delegators(:@frame, :iconify, :window)
def_delegators(:@frame, :fullscreen_available?)
def_delegators(:@frame, :iconify_available?)
def_delegators(:@frame, :toggle_terminal)
def_delegators(:@frame, :in_terminal?)

def_delegators(:@renderer, :width, :height)
# Deprecated. Use #base_width= instead.
Expand Down
85 changes: 81 additions & 4 deletions lib/rabbit/frame.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,16 @@
require "rabbit/gtk"
require "rexml/text"

begin
require "vte3"
rescue LoadError
end

require "rabbit/rabbit"
require "rabbit/utils"

module Rabbit

class Frame

include ScreenInfo
extend Forwardable

Expand All @@ -31,6 +34,8 @@ def initialize(logger, canvas)
@logger = logger
@canvas = canvas
@geometry = nil
@notebook = nil
@terminal = nil
end

def destroyed?
Expand Down Expand Up @@ -87,6 +92,8 @@ def init_gui(width, height, main_window, window_type=nil)
init_window(width, height, window_type)
@fullscreen = false
@main_window = main_window
@terminal.show if @terminal
@notebook.show if @notebook
@window.show
@canvas.post_init_gui
end
Expand All @@ -99,16 +106,51 @@ def iconify_available?
true
end

def toggle_terminal
return if @terminal.nil?
terminal_page = @notebook.page_num(@terminal)
if @notebook.current_page == terminal_page
@notebook.current_page = 0
else
@notebook.current_page = terminal_page
end
end

def in_terminal?
return false if @terminal.nil?
@notebook.current_page == @notebook.page_num(@terminal)
end

private
def init_window(width, height, window_type=nil)
window_type ||= :toplevel
@window = Gtk::ApplicationWindow.new(::Rabbit.application)
@window.set_default_size(width, height)
@window.parse_geometry(@geometry) if @geometry
@window.set_app_paintable(true)
if defined?(Vte::Terminal)
init_notebook
end
set_window_signal
setup_dnd
@canvas.attach_to(self, @window)
@canvas.attach_to(self, @window, @notebook)
if defined?(Vte::Terminal)
init_terminal
end
end

def init_notebook
@notebook = Gtk::Notebook.new
@notebook.show_tabs = false
provider = Gtk::CssProvider.new
provider.load(data: <<-CSS)
notebook {
border-width: 0px;
}
CSS
@notebook.style_context.add_provider(provider,
Gtk::StyleProvider::PRIORITY_USER)
@window.add(@notebook)
end

def set_window_signal
Expand Down Expand Up @@ -160,6 +202,28 @@ def setup_dnd
true
end
end

def init_terminal
@terminal = Vte::Terminal.new
# TODO: Support theme
terminal_font_description = ENV["RABBIT_TERMINAL_FONT_DESCRIPTION"]
if terminal_font_description
@terminal.font_desc =
Pango::FontDescription.new(terminal_font_description)
end
@notebook.add(@terminal)
pid = nil
@notebook.signal_connect(:switch_page) do |_, page,|
if page == @terminal
begin
Process.wait(pid, Process::WNOHANG) if pid
rescue SystemCallError
pid = nil
end
pid = @terminal.spawn if pid.nil?
end
end
end
end

class NullFrame
Expand All @@ -184,10 +248,16 @@ def fullscreen_available?
def iconify_available?
false
end

def toggle_terminal
end

def in_terminal?
false
end
end

class EmbedFrame < Frame

def update_title(new_title)
end

Expand All @@ -199,6 +269,13 @@ def iconify_available?
false
end

def toggle_terminal
end

def in_terminal?
false
end

def init_gui(width, height, main_window, window_type=nil)
@window = Gtk::EventBox.new
@window.set_size_request(width, height)
Expand Down
6 changes: 6 additions & 0 deletions lib/rabbit/keys.rb
Original file line number Diff line number Diff line change
Expand Up @@ -178,5 +178,11 @@ module Alt
Gdk::Keyval::KEY_t,
]
end

module ShiftControlAlt
TOGGLE_TERMINAL_KEYS = [
Gdk::Keyval::KEY_t,
]
end
end
end
28 changes: 26 additions & 2 deletions lib/rabbit/renderer/display/key-handler.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ def disconnect_key(keyval, modifier)
def init_key_handler
@user_accel_group = nil
init_accel_group
init_toggle_terminal_accel_group
end

def clear_user_accel_group
Expand All @@ -31,10 +32,12 @@ def clear_user_accel_group

def attach_key(window)
window.add_accel_group(@accel_group)
window.add_accel_group(@toggle_terminal_accel_group)
end

def detach_key(window)
window.remove_accel_group(@accel_group)
window.remove_accel_group(@toggle_terminal_accel_group)
end

def clear_keys
Expand All @@ -53,10 +56,31 @@ def init_accel_group
init_alt_keys
end

def set_keys(keys, mod, flags=nil, &block)
def init_toggle_terminal_accel_group
@toggle_terminal_accel_group = Gtk::AccelGroup.new
mod = Gdk::ModifierType::SHIFT_MASK |
Gdk::ModifierType::CONTROL_MASK |
Gdk::ModifierType::MOD1_MASK
keys = Keys::ShiftControlAlt::TOGGLE_TERMINAL_KEYS
set_keys(keys,
mod,
nil,
@toggle_terminal_accel_group) do |group, obj, val, modifier|
@canvas.activate("ToggleTerminal")
# TODO: Add canvas to a signal to detect terminal mode change and
# use it for the following code.
if @canvas.in_terminal?
@window.remove_accel_group(@accel_group)
else
@window.add_accel_group(@accel_group)
end
end
end

def set_keys(keys, mod, flags=nil, accel_group=@accel_group, &block)
flags ||= Gtk::AccelFlags::VISIBLE
keys.each do |val|
@accel_group.connect(val, mod, flags, &block)
accel_group.connect(val, mod, flags, &block)
end
end

Expand Down

0 comments on commit 16f4ad0

Please sign in to comment.