mirror of
https://github.com/Guake/guake.git
synced 2025-10-26 11:27:13 +00:00
423 lines
18 KiB
Python
423 lines
18 KiB
Python
# -*- coding: utf-8; -*-
|
|
"""
|
|
Copyright (C) 2007-2013 Guake authors
|
|
|
|
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 the Free Software Foundation; either version 2 of the
|
|
License, or (at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public
|
|
License along with this program; if not, write to the
|
|
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
|
Boston, MA 02110-1301 USA
|
|
"""
|
|
import logging
|
|
import subprocess
|
|
|
|
from xml.sax.saxutils import escape as xml_escape
|
|
|
|
import gi
|
|
|
|
gi.require_version("Gtk", "3.0")
|
|
gi.require_version("Vte", "2.91") # vte-0.38
|
|
from gi.repository import Gdk
|
|
from gi.repository import Gio
|
|
from gi.repository import Gtk
|
|
from gi.repository import Pango
|
|
from gi.repository import Vte
|
|
from guake.utils import RectCalculator
|
|
|
|
from guake.common import pixmapfile
|
|
from locale import gettext as _
|
|
|
|
log = logging.getLogger(__name__)
|
|
|
|
|
|
class GSettingHandler:
|
|
|
|
"""Handles gconf changes, if any gconf variable is changed, a
|
|
different method is called to handle this change.
|
|
"""
|
|
|
|
def __init__(self, guake_inst):
|
|
"""Constructor of GConfHandler, just add the guake dir to the
|
|
gconf client and bind the keys to its handler methods.
|
|
"""
|
|
self.guake = guake_inst
|
|
self.settings = guake_inst.settings
|
|
settings = self.settings
|
|
|
|
# Notification is not required for mouse_display/display-n because
|
|
# set_final_window_rect polls gconf and is called whenever Guake is
|
|
# shown or resized
|
|
|
|
settings.general.onChangedValue("use-trayicon", self.trayicon_toggled)
|
|
settings.general.onChangedValue("window-ontop", self.ontop_toggled)
|
|
settings.general.onChangedValue("tab-ontop", self.tab_ontop_toggled)
|
|
settings.general.onChangedValue("window-tabbar", self.tabbar_toggled)
|
|
settings.general.onChangedValue(
|
|
"fullscreen-hide-tabbar", self.fullscreen_hide_tabbar_toggled
|
|
)
|
|
settings.general.onChangedValue("window-height", self.size_changed)
|
|
settings.general.onChangedValue("window-width", self.size_changed)
|
|
settings.general.onChangedValue("window-valignment", self.alignment_changed)
|
|
settings.general.onChangedValue("window-halignment", self.alignment_changed)
|
|
settings.general.onChangedValue("window-vertical-displacement", self.alignment_changed)
|
|
settings.general.onChangedValue("window-horizontal-displacement", self.alignment_changed)
|
|
settings.style.onChangedValue("cursor-blink-mode", self.cursor_blink_mode_changed)
|
|
settings.style.onChangedValue("cursor-shape", self.cursor_shape_changed)
|
|
|
|
settings.general.onChangedValue("use-scrollbar", self.scrollbar_toggled)
|
|
settings.general.onChangedValue("history-size", self.history_size_changed)
|
|
settings.general.onChangedValue("infinite-history", self.infinite_history_changed)
|
|
settings.general.onChangedValue("scroll-output", self.keystroke_output)
|
|
settings.general.onChangedValue("scroll-keystroke", self.keystroke_toggled)
|
|
|
|
settings.general.onChangedValue("use-default-font", self.default_font_toggled)
|
|
settings.styleFont.onChangedValue("style", self.fstyle_changed)
|
|
settings.styleFont.onChangedValue("palette", self.fpalette_changed)
|
|
settings.styleFont.onChangedValue("allow-bold", self.allow_bold_toggled)
|
|
settings.styleFont.onChangedValue("bold-is-bright", self.bold_is_bright_toggled)
|
|
settings.styleBackground.onChangedValue("transparency", self.bgtransparency_changed)
|
|
|
|
settings.general.onChangedValue("compat-backspace", self.backspace_changed)
|
|
settings.general.onChangedValue("compat-delete", self.delete_changed)
|
|
settings.general.onChangedValue("custom-command_file", self.custom_command_file_changed)
|
|
settings.general.onChangedValue("max-tab-name-length", self.max_tab_name_length_changed)
|
|
settings.general.onChangedValue("display-tab-names", self.display_tab_names_changed)
|
|
|
|
def custom_command_file_changed(self, settings, key, user_data):
|
|
self.guake.load_custom_commands()
|
|
|
|
def trayicon_toggled(self, settings, key, user_data):
|
|
"""If the gconf var use_trayicon be changed, this method will
|
|
be called and will show/hide the trayicon.
|
|
"""
|
|
if hasattr(self.guake.tray_icon, "set_status"):
|
|
self.guake.tray_icon.set_status(settings.get_boolean(key))
|
|
else:
|
|
self.guake.tray_icon.set_visible(settings.get_boolean(key))
|
|
|
|
def ontop_toggled(self, settings, key, user_data):
|
|
"""If the gconf var window_ontop be changed, this method will
|
|
be called and will set the keep_above attribute in guake's
|
|
main window.
|
|
"""
|
|
self.guake.window.set_keep_above(settings.get_boolean(key))
|
|
|
|
def tab_ontop_toggled(self, settings, key, user_data):
|
|
""" tab_ontop changed
|
|
"""
|
|
self.guake.set_tab_position()
|
|
|
|
def tabbar_toggled(self, settings, key, user_data):
|
|
"""If the gconf var use_tabbar be changed, this method will be
|
|
called and will show/hide the tabbar.
|
|
"""
|
|
if settings.get_boolean(key):
|
|
self.guake.notebook_manager.set_notebooks_tabbar_visible(True)
|
|
else:
|
|
self.guake.notebook_manager.set_notebooks_tabbar_visible(False)
|
|
|
|
def fullscreen_hide_tabbar_toggled(self, settings, key, user_data):
|
|
"""If the gconf var fullscreen_hide_tabbar be changed, this method will be
|
|
called and will show/hide the tabbar when fullscreen.
|
|
"""
|
|
if not self.guake.fullscreen_manager.is_fullscreen():
|
|
return
|
|
|
|
if settings.get_boolean(key):
|
|
self.guake.notebook_manager.set_notebooks_tabbar_visible(False)
|
|
else:
|
|
self.guake.notebook_manager.set_notebooks_tabbar_visible(True)
|
|
|
|
def alignment_changed(self, settings, key, user_data):
|
|
"""If the gconf var window_halignment be changed, this method will
|
|
be called and will call the move function in guake.
|
|
"""
|
|
RectCalculator.set_final_window_rect(self.settings, self.guake.window)
|
|
self.guake.set_tab_position()
|
|
self.guake.force_move_if_shown()
|
|
|
|
def size_changed(self, settings, key, user_data):
|
|
"""If the gconf var window_height or window_width are changed,
|
|
this method will be called and will call the resize function
|
|
in guake.
|
|
"""
|
|
RectCalculator.set_final_window_rect(self.settings, self.guake.window)
|
|
|
|
def cursor_blink_mode_changed(self, settings, key, user_data):
|
|
"""Called when cursor blink mode settings has been changed
|
|
"""
|
|
terminal = (
|
|
self.guake.notebook_manager.get_terminal_by_uuid(user_data.get("terminal_uuid"))
|
|
if user_data
|
|
else None
|
|
)
|
|
terminals = (terminal,) if terminal else self.guake.notebook_manager.iter_terminals()
|
|
for term in terminals:
|
|
term.set_property("cursor-blink-mode", settings.get_int(key))
|
|
|
|
def cursor_shape_changed(self, settings, key, user_data):
|
|
"""Called when the cursor shape settings has been changed
|
|
"""
|
|
terminal = (
|
|
self.guake.notebook_manager.get_terminal_by_uuid(user_data.get("terminal_uuid"))
|
|
if user_data
|
|
else None
|
|
)
|
|
terminals = (terminal,) if terminal else self.guake.notebook_manager.iter_terminals()
|
|
for term in terminals:
|
|
term.set_property("cursor-shape", settings.get_int(key))
|
|
|
|
def scrollbar_toggled(self, settings, key, user_data):
|
|
"""If the gconf var use_scrollbar be changed, this method will
|
|
be called and will show/hide scrollbars of all terminals open.
|
|
"""
|
|
terminal = (
|
|
self.guake.notebook_manager.get_terminal_by_uuid(user_data.get("terminal_uuid"))
|
|
if user_data
|
|
else None
|
|
)
|
|
terminals = (terminal,) if terminal else self.guake.notebook_manager.iter_terminals()
|
|
for term in terminals:
|
|
# There is an hbox in each tab of the main notebook and it
|
|
# contains a Terminal and a Scrollbar. Since only have the
|
|
# Terminal here, we're going to use this to get the
|
|
# scrollbar and hide/show it.
|
|
hbox = term.get_parent()
|
|
if hbox is None:
|
|
continue
|
|
terminal, scrollbar = hbox.get_children()
|
|
if settings.get_boolean(key):
|
|
scrollbar.show()
|
|
else:
|
|
scrollbar.hide()
|
|
|
|
def history_size_changed(self, settings, key, user_data):
|
|
"""If the gconf var history_size be changed, this method will
|
|
be called and will set the scrollback_lines property of all
|
|
terminals open.
|
|
"""
|
|
lines = settings.get_int(key)
|
|
terminal = (
|
|
self.guake.notebook_manager.get_terminal_by_uuid(user_data.get("terminal_uuid"))
|
|
if user_data
|
|
else None
|
|
)
|
|
terminals = (terminal,) if terminal else self.guake.notebook_manager.iter_terminals()
|
|
for i in terminals:
|
|
i.set_scrollback_lines(lines)
|
|
|
|
def infinite_history_changed(self, settings, key, user_data):
|
|
if settings.get_boolean(key):
|
|
lines = -1
|
|
else:
|
|
lines = self.settings.general.get_int("history-size")
|
|
terminal = (
|
|
self.guake.notebook_manager.get_terminal_by_uuid(user_data.get("terminal_uuid"))
|
|
if user_data
|
|
else None
|
|
)
|
|
terminals = (terminal,) if terminal else self.guake.notebook_manager.iter_terminals()
|
|
for i in terminals:
|
|
i.set_scrollback_lines(lines)
|
|
|
|
def keystroke_output(self, settings, key, user_data):
|
|
"""If the gconf var scroll_output be changed, this method will
|
|
be called and will set the scroll_on_output in all terminals
|
|
open.
|
|
"""
|
|
terminal = (
|
|
self.guake.notebook_manager.get_terminal_by_uuid(user_data.get("terminal_uuid"))
|
|
if user_data
|
|
else None
|
|
)
|
|
terminals = (terminal,) if terminal else self.guake.notebook_manager.iter_terminals()
|
|
for i in terminals:
|
|
i.set_scroll_on_output(settings.get_boolean(key))
|
|
|
|
def keystroke_toggled(self, settings, key, user_data):
|
|
"""If the gconf var scroll_keystroke be changed, this method
|
|
will be called and will set the scroll_on_keystroke in all
|
|
terminals open.
|
|
"""
|
|
terminal = (
|
|
self.guake.notebook_manager.get_terminal_by_uuid(user_data.get("terminal_uuid"))
|
|
if user_data
|
|
else None
|
|
)
|
|
terminals = (terminal,) if terminal else self.guake.notebook_manager.iter_terminals()
|
|
for i in terminals:
|
|
i.set_scroll_on_keystroke(settings.get_boolean(key))
|
|
|
|
def default_font_toggled(self, settings, key, user_data):
|
|
"""If the gconf var use_default_font be changed, this method
|
|
will be called and will change the font style to the gnome
|
|
default or to the chosen font in style/font/style in all
|
|
terminals open.
|
|
"""
|
|
font_name = None
|
|
if settings.get_boolean(key):
|
|
gio_settings = Gio.Settings("org.gnome.desktop.interface")
|
|
font_name = gio_settings.get_string("monospace-font-name")
|
|
else:
|
|
font_name = self.settings.styleFont.get_string("style")
|
|
if not font_name:
|
|
log.error("Error: unable to find font name (%s)", font_name)
|
|
return
|
|
font = Pango.FontDescription(font_name)
|
|
if not font:
|
|
log.error("Error: unable to load font (%s)", font_name)
|
|
return
|
|
terminal = (
|
|
self.guake.notebook_manager.get_terminal_by_uuid(user_data.get("terminal_uuid"))
|
|
if user_data
|
|
else None
|
|
)
|
|
terminals = (terminal,) if terminal else self.guake.notebook_manager.iter_terminals()
|
|
for i in terminals:
|
|
i.set_font(font)
|
|
|
|
def allow_bold_toggled(self, settings, key, user_data):
|
|
"""If the gconf var allow_bold is changed, this method will be called
|
|
and will change the VTE terminal o.
|
|
displaying characters in bold font.
|
|
"""
|
|
terminal = (
|
|
self.guake.notebook_manager.get_terminal_by_uuid(user_data.get("terminal_uuid"))
|
|
if user_data
|
|
else None
|
|
)
|
|
terminals = (terminal,) if terminal else self.guake.notebook_manager.iter_terminals()
|
|
for term in terminals:
|
|
term.set_allow_bold(settings.get_boolean(key))
|
|
|
|
def bold_is_bright_toggled(self, settings, key, user_data):
|
|
"""If the dconf var bold_is_bright is changed, this method will be called
|
|
and will change the VTE terminal to toggle auto-brightened bold text.
|
|
"""
|
|
try:
|
|
terminal = self.guake.notebook_manager.get_terminal_by_uuid(
|
|
user_data.get("terminal_uuid") if user_data else None
|
|
)
|
|
terminals = (terminal,) if terminal else self.guake.notebook_manager.iter_terminals()
|
|
for term in terminals:
|
|
term.set_bold_is_bright(settings.get_boolean(key))
|
|
except: # pylint: disable=bare-except
|
|
log.error("set_bold_is_bright not supported by your version of VTE")
|
|
|
|
def palette_font_and_background_color_toggled(self, settings, key, user_data):
|
|
"""If the gconf var use_palette_font_and_background_color be changed, this method
|
|
will be called and will change the font color and the background color to the color
|
|
defined in the palette.
|
|
"""
|
|
self.settings.styleFont.triggerOnChangedValue(self.settings.styleFont, "palette")
|
|
|
|
def fstyle_changed(self, settings, key, user_data):
|
|
"""If the gconf var style/font/style be changed, this method
|
|
will be called and will change the font style in all terminals
|
|
open.
|
|
"""
|
|
terminal_uuid = user_data.get("terminal_uuid") if user_data else None
|
|
|
|
if terminal_uuid:
|
|
terminal = self.guake.notebook_manager.get_terminal_by_uuid(terminal_uuid)
|
|
terminals = (terminal,) if terminal else tuple()
|
|
else:
|
|
terminals = self.guake.notebook_manager.iter_terminals()
|
|
|
|
font = Pango.FontDescription(settings.get_string(key))
|
|
for i in terminals:
|
|
i.set_font(font)
|
|
|
|
def fpalette_changed(self, settings, key, user_data):
|
|
"""If the gconf var style/font/palette be changed, this method
|
|
will be called and will change the color scheme in all terminals
|
|
open.
|
|
"""
|
|
self.guake.set_colors_from_settings(
|
|
terminal_uuid=user_data.get("terminal_uuid") if user_data else None
|
|
)
|
|
|
|
def bgtransparency_changed(self, settings, key, user_data):
|
|
"""If the gconf var style/background/transparency be changed, this
|
|
method will be called and will set the saturation and transparency
|
|
properties in all terminals open.
|
|
"""
|
|
self.guake.set_background_color_from_settings(
|
|
terminal_uuid=user_data.get("terminal_uuid") if user_data else None
|
|
)
|
|
|
|
def getEraseBinding(self, str):
|
|
if str == "auto":
|
|
return Vte.EraseBinding(0)
|
|
if str == "ascii-backspace":
|
|
return Vte.EraseBinding(1)
|
|
if str == "ascii-delete":
|
|
return Vte.EraseBinding(2)
|
|
if str == "delete-sequence":
|
|
return Vte.EraseBinding(3)
|
|
if str == "tty":
|
|
return Vte.EraseBinding(4)
|
|
|
|
def backspace_changed(self, settings, key, user_data):
|
|
"""If the gconf var compat_backspace be changed, this method
|
|
will be called and will change the binding configuration in
|
|
all terminals open.
|
|
"""
|
|
terminal = (
|
|
self.guake.notebook_manager.get_terminal_by_uuid(user_data.get("terminal_uuid"))
|
|
if user_data
|
|
else None
|
|
)
|
|
terminals = (terminal,) if terminal else self.guake.notebook_manager.iter_terminals()
|
|
for i in terminals:
|
|
i.set_backspace_binding(self.getEraseBinding(settings.get_string(key)))
|
|
|
|
def delete_changed(self, settings, key, user_data):
|
|
"""If the gconf var compat_delete be changed, this method
|
|
will be called and will change the binding configuration in
|
|
all terminals open.
|
|
"""
|
|
terminal = (
|
|
self.guake.notebook_manager.get_terminal_by_uuid(user_data.get("terminal_uuid"))
|
|
if user_data
|
|
else None
|
|
)
|
|
terminals = (terminal,) if terminal else self.guake.notebook_manager.iter_terminals()
|
|
for i in terminals:
|
|
i.set_delete_binding(self.getEraseBinding(settings.get_string(key)))
|
|
|
|
def max_tab_name_length_changed(self, settings, key, user_data):
|
|
"""If the gconf var max_tab_name_length be changed, this method will
|
|
be called and will set the tab name length limit.
|
|
"""
|
|
|
|
# avoid get window title before terminal is ready
|
|
if self.guake.notebook_manager.get_current_notebook().get_current_terminal() is None:
|
|
return
|
|
# avoid get window title before terminal is ready
|
|
if (
|
|
self.guake.notebook_manager.get_current_notebook()
|
|
.get_current_terminal()
|
|
.get_window_title()
|
|
is None
|
|
):
|
|
return
|
|
|
|
self.guake.recompute_tabs_titles()
|
|
|
|
def display_tab_names_changed(self, settings, key, user_data):
|
|
"""If the gconf var display-tab-names was changed, this method will
|
|
be called and will update tab names.
|
|
"""
|
|
self.guake.display_tab_names = settings.get_int("display-tab-names")
|
|
self.guake.recompute_tabs_titles()
|