Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Window background image #612

Draft
wants to merge 3 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion terminatorlib/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,11 @@
'always_on_top' : False,
'hide_on_lose_focus' : False,
'sticky' : False,
'window_background_type' : 'transparent',
'window_background_image' : '',
'window_background_image_mode' : 'stretch_and_fill',
'window_background_image_align_horiz' : 'center',
'window_background_image_align_vert' : 'middle',
'use_custom_url_handler': False,
'custom_url_handler' : '',
'disable_real_transparency' : False,
Expand Down Expand Up @@ -565,7 +570,7 @@ def defaults_to_configspec(self):

keytype = '%s(default=%s)' % (keytype, value)

if key == 'custom_url_handler':
if key in ('custom_url_handler', 'window_background_image'):
keytype = 'string(default="")'

section[key] = keytype
Expand Down
4 changes: 2 additions & 2 deletions terminatorlib/terminal.py
Original file line number Diff line number Diff line change
Expand Up @@ -191,11 +191,9 @@ def set_background_image(self,image):
try:
bg_pixbuf = GdkPixbuf.Pixbuf.new_from_file(image)
self.background_image = Gdk.cairo_surface_create_from_pixbuf(bg_pixbuf, 1, None)
self.vte.set_clear_background(False)
self.vte.connect("draw", self.background_draw)
except Exception as e:
self.background_image = None
self.vte.set_clear_background(True)
err('error loading background image: %s, %s' % (type(e).__name__,e))

def get_vte(self):
Expand Down Expand Up @@ -720,6 +718,8 @@ def reconfigure(self, _widget=None):
self.bgcolor = Gdk.RGBA()
self.bgcolor.parse(self.config['background_color'])

self.vte.set_clear_background(False)

if self.config['background_type'] in ('transparent', 'image'):
self.bgcolor.alpha = self.config['background_darkness']
else:
Expand Down
4 changes: 4 additions & 0 deletions terminatorlib/terminator.py
Original file line number Diff line number Diff line change
Expand Up @@ -500,6 +500,10 @@ def reconfigure(self):
self.style_providers[idx],
Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION+idx)

# Apply config to all windows
for window in self.windows:
window.apply_config()

# Cause all the terminals to reconfigure
for terminal in self.terminals:
terminal.reconfigure()
Expand Down
72 changes: 71 additions & 1 deletion terminatorlib/window.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import time
import uuid
import gi
from gi.repository import GObject
from gi.repository import GObject, GdkPixbuf, cairo
from gi.repository import Gtk, Gdk

from .util import dbg, err, make_uuid, display_manager
Expand Down Expand Up @@ -155,6 +155,8 @@ def apply_config(self):
skiptaskbar = self.config['hide_from_taskbar']
alwaysontop = self.config['always_on_top']
sticky = self.config['sticky']
background_type = self.config['window_background_type']
background_image_path = self.config['window_background_image']

if options:
if options.maximise:
Expand All @@ -178,6 +180,11 @@ def apply_config(self):
else:
self.set_iconified(hidden)

if background_type == 'image' and background_image_path != '':
self.set_background_image(background_image_path)
else:
self.background_image = None

def apply_icon(self, requested_icon):
"""Set the window icon"""
icon_theme = Gtk.IconTheme.get_default()
Expand Down Expand Up @@ -392,6 +399,16 @@ def set_real_transparency(self, value=True):
visual = screen.get_rgba_visual()
if visual:
self.set_visual(visual)

def set_background_image(self, image):
try:
bg_pixbuf = GdkPixbuf.Pixbuf.new_from_file(image)
self.background_image = Gdk.cairo_surface_create_from_pixbuf(bg_pixbuf, 1, None)
self.connect("draw", self.background_draw)
except Exception as e:
self.background_image = None
err('error loading background image: %s, %s' % (type(e).__name__,e))


def show(self, startup=False):
"""Undo the startup show request if started in hidden mode"""
Expand Down Expand Up @@ -968,6 +985,59 @@ def create_layout(self, layout):
if 'last_active_window' in layout and layout['last_active_window'] == 'True':
self.terminator.last_active_window = self.uuid

# TODO this is almost identical to Terminal.background_draw.
# The two functions should be merged to avoid code duplication.
def background_draw(self, window, cr):
if self.background_image is None:
return False

# save cairo context
cr.save()

# draw background image
image_mode = self.config['window_background_image_mode']
image_align_horiz = self.config['window_background_image_align_horiz']
image_align_vert = self.config['window_background_image_align_vert']

rect = window.get_allocation()
xratio = float(rect.width) / float(self.background_image.get_width())
yratio = float(rect.height) / float(self.background_image.get_height())
if image_mode == 'stretch_and_fill':
# keep stretched ratios
xratio = xratio
yratio = yratio
elif image_mode == 'scale_and_fit':
ratio = min(xratio, yratio)
xratio = yratio = ratio
elif image_mode == 'scale_and_crop':
ratio = max(xratio, yratio)
xratio = yratio = ratio
else:
xratio = yratio = 1
cr.scale(xratio, yratio)

xoffset = 0
yoffset = 0
if image_align_horiz == 'center':
xoffset = (rect.width / xratio - self.background_image.get_width()) / 2
elif image_align_horiz == 'right':
xoffset = rect.width / xratio - self.background_image.get_width()

if image_align_vert == 'middle':
yoffset = (rect.height / yratio - self.background_image.get_height()) / 2
elif image_align_vert == 'bottom':
yoffset = rect.height / yratio - self.background_image.get_height()

cr.set_source_surface(self.background_image, xoffset, yoffset)
cr.get_source().set_filter(cairo.Filter.FAST)
if image_mode == 'tiling':
cr.get_source().set_extend(cairo.Extend.REPEAT)

cr.paint()

# restore cairo context
cr.restore()

class WindowTitle(object):
"""Class to handle the setting of the window title"""

Expand Down
Loading