Exemplo n.º 1
0
    def __init__(self, directory=None, command=None):
        super(XfConTerminal, self).__init__()

        self.term_settings = XfTermSettings()
        self.settings = XfConSettings.Instance()

        self.match_valid = False
        self.match_pair = None

        self.terminal = vte.Terminal()
        self.terminal.show()
        self.pack_start(self.terminal)

        adj = self.terminal.get_adjustment()
        self.scrollbar = gtk.VScrollbar(adj)
        self.scrollbar.set_no_show_all(True)
        self.pack_start(self.scrollbar, False, False)

        self.__configure_terminal()
        self.__bind_signals()
        self.__bind_config()

        params = {}
        params["directory"] = directory
        params["command"] = command

        self.shell_params = self.__get_fork_params(params)
        self.pid = self.terminal.fork_command(**self.shell_params)
        self.show()
Exemplo n.º 2
0
class XfConTerminal(gtk.HBox, XfConObject):
    __gsignals__ = XfConObject.XfConSignals()
    # Remember the location of most recent directory.
    class_last_path = "~"

    def __init__(self, directory=None, command=None):
        super(XfConTerminal, self).__init__()

        self.term_settings = XfTermSettings()
        self.settings = XfConSettings.Instance()

        self.match_valid = False
        self.match_pair = None

        self.terminal = vte.Terminal()
        self.terminal.show()
        self.pack_start(self.terminal)

        adj = self.terminal.get_adjustment()
        self.scrollbar = gtk.VScrollbar(adj)
        self.scrollbar.set_no_show_all(True)
        self.pack_start(self.scrollbar, False, False)

        self.__configure_terminal()
        self.__bind_signals()
        self.__bind_config()

        params = {}
        params["directory"] = directory
        params["command"] = command

        self.shell_params = self.__get_fork_params(params)
        self.pid = self.terminal.fork_command(**self.shell_params)
        self.show()

    def __bind_config(self):
        self.term_settings.connect("notify::term-scroll-on-output", self.__config_set_scroll)
        self.term_settings.connect("notify::term-scroll-on-keypress", self.__config_set_scroll)
        self.term_settings.connect("notify::term-scroll-history-size", self.__config_set_scroll)
        self.term_settings.connect("notify::term-scroll-visible", self.__config_set_scroll)
        self.term_settings.connect("notify::term-emulator-font", self.__config_set_font_style)
        self.term_settings.connect("notify::term-emulator-opacity", self.__config_set_background_transparency)

    def __bind_signals(self):
        self.terminal.connect("button-press-event", self.__on_button_press)
        self.terminal.connect("expose-event", self.__apply_config)
        self.terminal.connect("child-exited", self.__on_child_exited)
        self.terminal.connect("focus-in-event", self.__on_focus_in)
        self.terminal.connect("focus-out-event", self.__on_focus_out)

    def __on_focus_in(self, source, event):
        self.emit("focus-in-event", event)
        XfConKeyBinder.register(
            self,
            [
                (self.settings.get_property("key-clipboard-copy"), self.__on_menu_copy),
                (self.settings.get_property("key-clipboard-paste"), self.__on_menu_paste),
                (self.settings.get_property("key-view-split-horizontal"), self.__on_split_horizontal),
                (self.settings.get_property("key-view-split-vertical"), self.__on_split_vertical),
                (self.settings.get_property("key-view-activate-next"), self.__on_activate_next),
                (self.settings.get_property("key-view-activate-previous"), self.__on_activate_previous),
            ],
        )

    def __on_focus_out(self, source, event):
        XfConKeyBinder.unregister(self)
        self.emit("focus-out-event", event)

    def __apply_config(self, *ignore):
        # there seem to be certain misfeatures in the vte terminal implementation
        # these cause the terminal to ignore initial configuration,
        # if applied before the box is shown
        self.terminal.disconnect_by_func(self.__apply_config)
        self.__config_set_background_transparency()
        self.__config_set_font_style()
        self.__config_set_scroll()
        self.__config_set_keybindings()

    def __config_set_font_style(self, *ignore):
        font = FontDescription(self.term_settings.get_property("term-emulator-font"))
        self.terminal.set_font(font)

    def __config_set_background_transparency(self, *ignore):
        transparency = self.term_settings.get_property("term-emulator-opacity")
        self.terminal.set_opacity(int(transparency * 65535))

    def __config_set_scroll(self, *ignore):
        self.terminal.set_scroll_on_output(self.term_settings.get_property("term-scroll-on-output"))
        self.terminal.set_scroll_on_keystroke(self.term_settings.get_property("term-scroll-on-keypress"))
        self.terminal.set_scrollback_lines(self.term_settings.get_property("term-scroll-history-size"))
        self.scrollbar.set_visible(self.term_settings.get_property("term-scroll-visible"))

    def __config_set_keybindings(self, *ignore):
        self.terminal.set_backspace_binding(vte.ERASE_AUTO)
        self.terminal.set_delete_binding(vte.ERASE_AUTO)

    def __on_button_press(self, terminal, event):
        self.match_pair = self.terminal.match_check(
            int(event.x / self.terminal.get_char_width()), int(event.y / self.terminal.get_char_height())
        )
        self.match_valid = self.match_pair != None

        if event.button == 3:
            menu = self.__build_menu()
            self.emit_menu_show()
            menu.popup(None, None, None, event.button, event.get_time())

    def __on_menu_copy(self, *ignore):
        if self.terminal.get_has_selection():
            self.terminal.copy_clipboard()
        elif self.match_valid:
            gtk.clipboard_get().set_text(self.match_pair[0])
        return True

    def __on_menu_paste(self, *ignore):
        self.terminal.paste_clipboard()
        return True

    def __on_split_horizontal(self, *ignore):
        self.emit_view_split_horizontal(XfConTerminal())

    def __on_split_vertical(self, *ignore):
        self.emit_view_split_vertical(XfConTerminal())

    def __on_activate_next(self, *ignore):
        self.emit_view_activate_next()

    def __on_activate_previous(self, *ignore):
        self.emit_view_activate_previous()

    def __on_menu_close(self, menu):
        menu.destroy()
        self.emit_menu_hide()

    def __on_child_exited(self, *ignore):
        self.emit_view_terminate()

    def __build_menu(self):
        menu = gtk.Menu()
        menu.connect("selection-done", self.__on_menu_close)
        menu.show()

        item = gtk.ImageMenuItem(gtk.STOCK_COPY)
        item.set_label(_("Copy"))
        item.set_sensitive(self.terminal.get_has_selection() | self.match_valid)
        item.show()
        item.connect("activate", self.__on_menu_copy)
        menu.add(item)

        item = gtk.ImageMenuItem(gtk.STOCK_PASTE)
        item.set_label(_("Paste"))
        item.show()
        item.connect("activate", self.__on_menu_paste)
        menu.add(item)

        separator = gtk.SeparatorMenuItem()
        separator.show()
        menu.add(separator)

        item = gtk.ImageMenuItem(gtk.STOCK_ORIENTATION_LANDSCAPE)
        item.set_label(_("Split Horizontal"))
        item.show()
        item.connect("activate", self.__on_split_horizontal)
        menu.add(item)

        item = gtk.ImageMenuItem(gtk.STOCK_ORIENTATION_PORTRAIT)
        item.set_label(_("Split Vertical"))
        item.show()
        item.connect("activate", self.__on_split_vertical)
        menu.add(item)

        self.emit_menu_build(menu)
        return menu

    def destroy(self):
        start_new_thread(self.__delete_shell, (self.pid,))
        XfConKeyBinder.unregister(self)
        XfConTerminal.class_last_path = "~"
        super(self.__class__, self).destroy()

    def grab_focus(self):
        self.terminal.grab_focus()

    def __get_fork_params(self, params=None):
        if params["command"] is None:
            params["command"] = os.environ["SHELL"]
            if self.term_settings.get_property("term-shell-login"):
                params["loglastlog"] = True
                params["argv"] = ["-xv"]

        if params["directory"] is None:
            if self.term_settings.get_property("term-share-cwd"):
                params["directory"] = XfConTerminal.class_last_path
            else:
                params["directory"] = "~"

        params["directory"] = os.path.expanduser(params["directory"])
        params["command"] = os.path.realpath(params["command"])
        return params

    def __delete_shell(self, pid):
        try:
            os.kill(pid, signal.SIGTERM)
            sleep(3)
            os.kill(pid, signal.SIGKILL)
        except (OSError):
            # most likely process died already
            pass

    def __configure_terminal(self):
        self.terminal.set_word_chars(self.term_settings.get_property("term-emulator-word-chars"))
        self.terminal.set_audible_bell(self.term_settings.get_property("term-emulator-bell-audible"))
        self.terminal.set_visible_bell(self.term_settings.get_property("term-emulator-bell-visual"))
        self.terminal.set_sensitive(True)
        self.terminal.set_flags(gtk.CAN_DEFAULT)
        self.terminal.set_flags(gtk.CAN_FOCUS)

    def get_name(self):
        return _("Terminal #{num_pages}")

    def get_icon(self):
        return None