- Floating windows are stored by percentage of screen space

- 'Any' option added to monitor list to allow no specific screen to be chosen
- Fixed up X11 floating position options
This commit is contained in:
trigg 2024-04-06 19:50:54 +01:00
parent b8ef07c943
commit 5933571297
8 changed files with 226 additions and 140 deletions

View file

@ -241,10 +241,10 @@ class Discover:
self.voice_overlay.set_horz_edge_padding(config.getint( self.voice_overlay.set_horz_edge_padding(config.getint(
"main", "horz_edge_padding", fallback=0)) "main", "horz_edge_padding", fallback=0))
floating = config.getboolean("main", "floating", fallback=False) floating = config.getboolean("main", "floating", fallback=False)
floating_x = config.getint("main", "floating_x", fallback=0) floating_x = config.getfloat("main", "floating_x", fallback=0.0)
floating_y = config.getint("main", "floating_y", fallback=0) floating_y = config.getfloat("main", "floating_y", fallback=0.0)
floating_w = config.getint("main", "floating_w", fallback=400) floating_w = config.getfloat("main", "floating_w", fallback=0.1)
floating_h = config.getint("main", "floating_h", fallback=400) floating_h = config.getfloat("main", "floating_h", fallback=0.1)
self.voice_overlay.set_order( self.voice_overlay.set_order(
config.getint("main", "order", fallback=0)) config.getint("main", "order", fallback=0))
self.voice_overlay.set_hide_on_mouseover( self.voice_overlay.set_hide_on_mouseover(
@ -309,10 +309,10 @@ class Discover:
except: except:
pass pass
floating = config.getboolean("text", "floating", fallback=True) floating = config.getboolean("text", "floating", fallback=True)
floating_x = config.getint("text", "floating_x", fallback=0) floating_x = config.getfloat("text", "floating_x", fallback=0.0)
floating_y = config.getint("text", "floating_y", fallback=0) floating_y = config.getfloat("text", "floating_y", fallback=0.0)
floating_w = config.getint("text", "floating_w", fallback=400) floating_w = config.getfloat("text", "floating_w", fallback=0.1)
floating_h = config.getint("text", "floating_h", fallback=400) floating_h = config.getfloat("text", "floating_h", fallback=0.1)
channel = config.get("text", "channel", fallback="0") channel = config.get("text", "channel", fallback="0")
guild = config.get("text", "guild", fallback="0") guild = config.get("text", "guild", fallback="0")
@ -357,14 +357,14 @@ class Discover:
pass pass
floating = config.getboolean( floating = config.getboolean(
"notification", "floating", fallback=False) "notification", "floating", fallback=False)
floating_x = config.getint( floating_x = config.getfloat(
"notification", "floating_x", fallback=0) "notification", "floating_x", fallback=0.0)
floating_y = config.getint( floating_y = config.getfloat(
"notification", "floating_y", fallback=0) "notification", "floating_y", fallback=0.0)
floating_w = config.getint( floating_w = config.getfloat(
"notification", "floating_w", fallback=400) "notification", "floating_w", fallback=0.1)
floating_h = config.getint( floating_h = config.getfloat(
"notification", "floating_h", fallback=400) "notification", "floating_h", fallback=0.1)
font = config.get("notification", "font", fallback=None) font = config.get("notification", "font", fallback=None)
self.notification_overlay.set_bg(json.loads(config.get( self.notification_overlay.set_bg(json.loads(config.get(
"notification", "bg_col", fallback="[0.0,0.0,0.0,0.5]"))) "notification", "bg_col", fallback="[0.0,0.0,0.0,0.5]")))

View file

@ -24,12 +24,14 @@ log = logging.getLogger(__name__)
class DraggableWindow(Gtk.Window): class DraggableWindow(Gtk.Window):
"""An X11 window which can be moved and resized""" """An X11 window which can be moved and resized"""
def __init__(self, pos_x=0, pos_y=0, width=300, height=300, message="Message", settings=None): def __init__(self, pos_x=0.0, pos_y=0.0, width=0.1, height=0.1, message="Message", settings=None, monitor=None):
Gtk.Window.__init__(self, type=Gtk.WindowType.POPUP) Gtk.Window.__init__(self, type=Gtk.WindowType.POPUP)
self.pos_x = pos_x self.monitor = monitor
self.pos_y = pos_y (screen_x, screen_y, screen_width, screen_height) = self.get_display_coords()
self.width = max(100, width) self.pos_x = pos_x * screen_width
self.height = max(100, height) self.pos_y = pos_y * screen_height
self.width = max(40, width * screen_width)
self.height = max(40, height * screen_height)
self.settings = settings self.settings = settings
self.message = message self.message = message
self.set_size_request(50, 50) self.set_size_request(50, 50)
@ -50,7 +52,6 @@ class DraggableWindow(Gtk.Window):
self.compositing = True self.compositing = True
self.set_app_paintable(True) self.set_app_paintable(True)
self.monitor = 0
self.drag_type = None self.drag_type = None
self.drag_x = 0 self.drag_x = 0
@ -65,7 +66,17 @@ class DraggableWindow(Gtk.Window):
""" """
self.set_decorated(False) self.set_decorated(False)
self.set_keep_above(True) self.set_keep_above(True)
self.move(self.pos_x, self.pos_y)
(screen_x, screen_y, screen_width, screen_height) = self.get_display_coords()
self.width = min(self.width, screen_width)
self.height = min(self.height, screen_height)
self.pos_x = max(0, self.pos_x)
self.pos_x = min(screen_width - self.width, self.pos_x)
self.pos_y = max(0, self.pos_y)
self.pos_y = min(screen_height - self.height, self.pos_y)
self.move(self.pos_x + screen_x, self.pos_y + screen_y)
self.resize(self.width, self.height) self.resize(self.width, self.height)
def drag(self, _w, event): def drag(self, _w, event):
@ -73,8 +84,10 @@ class DraggableWindow(Gtk.Window):
if event.state & Gdk.ModifierType.BUTTON1_MASK: if event.state & Gdk.ModifierType.BUTTON1_MASK:
if self.drag_type == 1: if self.drag_type == 1:
# Center is move # Center is move
self.pos_x = event.x_root - self.drag_x (screen_x, screen_y, screen_width,
self.pos_y = event.y_root - self.drag_y screen_height) = self.get_display_coords()
self.pos_x = (event.x_root - screen_x) - self.drag_x
self.pos_y = (event.y_root - screen_y) - self.drag_y
self.force_location() self.force_location()
elif self.drag_type == 2: elif self.drag_type == 2:
# Right edge # Right edge
@ -86,7 +99,7 @@ class DraggableWindow(Gtk.Window):
self.height += event.y - self.drag_y self.height += event.y - self.drag_y
self.drag_y = event.y self.drag_y = event.y
self.force_location() self.force_location()
else: elif self.drag_type == 4:
# Bottom Right # Bottom Right
self.width += event.x - self.drag_x self.width += event.x - self.drag_x
self.height += event.y - self.drag_y self.height += event.y - self.drag_y
@ -137,11 +150,25 @@ class DraggableWindow(Gtk.Window):
context.rectangle(0, window_height - 32, window_width, 32) context.rectangle(0, window_height - 32, window_width, 32)
context.fill() context.fill()
def get_display_coords(self):
display = Gdk.Display.get_default()
if "get_monitor" in dir(display):
monitor = display.get_monitor(self.monitor)
if monitor:
geometry = monitor.get_geometry()
return (geometry.x, geometry.y, geometry.width, geometry.height)
return (0, 0, 1920, 1080) # We're in trouble
def get_coords(self): def get_coords(self):
"""Return window position and size""" """Return window position and size"""
(screen_x, screen_y, screen_width, screen_height) = self.get_display_coords()
scale = self.get_scale_factor() scale = self.get_scale_factor()
(pos_x, pos_y) = self.get_position() (pos_x, pos_y) = self.get_position()
pos_x = float(max(0, pos_x - screen_x))
pos_y = float(max(0, pos_y - screen_y))
(width, height) = self.get_size() (width, height) = self.get_size()
width = float(width)
height = float(height)
pos_x = pos_x / scale pos_x = pos_x / scale
pos_y = pos_y / scale pos_y = pos_y / scale
return (pos_x, pos_y, width, height) return (pos_x / screen_width, pos_y / screen_height, width / screen_width, height / screen_height)

View file

@ -30,12 +30,16 @@ log = logging.getLogger(__name__)
class DraggableWindowWayland(Gtk.Window): class DraggableWindowWayland(Gtk.Window):
"""A Wayland full-screen window which can be moved and resized""" """A Wayland full-screen window which can be moved and resized"""
def __init__(self, pos_x=0, pos_y=0, width=300, height=300, message="Message", settings=None, steamos=False, monitor=None): def __init__(self, pos_x=0.0, pos_y=0.0, width=0.1, height=0.1, message="Message", settings=None, steamos=False, monitor=None):
Gtk.Window.__init__(self, type=Gtk.WindowType.TOPLEVEL) Gtk.Window.__init__(self, type=Gtk.WindowType.TOPLEVEL)
self.pos_x = pos_x if steamos:
self.pos_y = pos_y monitor = 0
self.width = max(40, width) self.monitor = monitor
self.height = max(40, height) (screen_x, screen_y, screen_width, screen_height) = self.get_display_coords()
self.pos_x = pos_x * screen_width
self.pos_y = pos_y * screen_height
self.width = max(40, width * screen_width)
self.height = max(40, height * screen_height)
self.settings = settings self.settings = settings
self.message = message self.message = message
self.set_size_request(50, 50) self.set_size_request(50, 50)
@ -55,6 +59,9 @@ class DraggableWindowWayland(Gtk.Window):
self.drag_y = 0 self.drag_y = 0
if GtkLayerShell and not steamos: if GtkLayerShell and not steamos:
GtkLayerShell.init_for_window(self) GtkLayerShell.init_for_window(self)
display = Gdk.Display.get_default()
if "get_monitor" in dir(display):
monitor = display.get_monitor(self.monitor)
if monitor: if monitor:
GtkLayerShell.set_monitor(self, monitor) GtkLayerShell.set_monitor(self, monitor)
GtkLayerShell.set_layer(self, GtkLayerShell.Layer.TOP) GtkLayerShell.set_layer(self, GtkLayerShell.Layer.TOP)
@ -84,13 +91,14 @@ class DraggableWindowWayland(Gtk.Window):
def force_location(self): def force_location(self):
"""Move the window to previously given co-ords. In wayland just clip to current screen""" """Move the window to previously given co-ords. In wayland just clip to current screen"""
(size_x, size_y) = self.get_size() (screen_x, screen_y, screen_width, screen_height) = self.get_display_coords()
self.width = min(self.width, size_x) self.width = min(self.width, screen_width)
self.height = min(self.height, size_y) self.height = min(self.height, screen_height)
self.pos_x = max(0, self.pos_x) self.pos_x = max(0, self.pos_x)
self.pos_x = min(size_x - self.width, self.pos_x) self.pos_x = min(screen_width - self.width, self.pos_x)
self.pos_y = max(0, self.pos_y) self.pos_y = max(0, self.pos_y)
self.pos_y = min(size_y - self.height, self.pos_y) self.pos_y = min(screen_height - self.height, self.pos_y)
self.queue_draw() self.queue_draw()
def drag(self, _w, event): def drag(self, _w, event):
@ -181,6 +189,16 @@ class DraggableWindowWayland(Gtk.Window):
context.fill() context.fill()
context.restore() context.restore()
def get_display_coords(self):
display = Gdk.Display.get_default()
if "get_monitor" in dir(display):
monitor = display.get_monitor(self.monitor)
if monitor:
geometry = monitor.get_geometry()
return (geometry.x, geometry.y, geometry.width, geometry.height)
return (0, 0, 1920, 1080) # We're in trouble
def get_coords(self): def get_coords(self):
"""Return the position and size of the window""" """Return the position and size of the window"""
return (self.pos_x, self.pos_y, self.width, self.height) (screen_x, screen_y, screen_width, screen_height) = self.get_display_coords()
return (float(self.pos_x) / screen_width, float(self.pos_y) / screen_height, float(self.width) / screen_width, float(self.height) / screen_height)

View file

@ -258,7 +258,9 @@ class NotificationOverlayWindow(OverlayWindow):
layout.set_auto_dir(True) layout.set_auto_dir(True)
layout.set_markup(message, -1) layout.set_markup(message, -1)
attr = layout.get_attributes() attr = layout.get_attributes()
width = self.limit_width if self.width > self.limit_width else self.width (floating_x, floating_y, floating_width,
floating_height) = self.get_floating_coords()
width = self.limit_width if floating_width > self.limit_width else floating_width
layout.set_width((Pango.SCALE * (width - layout.set_width((Pango.SCALE * (width -
(self.border_radius * 4 + icon_width + icon_pad)))) (self.border_radius * 4 + icon_width + icon_pad))))
layout.set_spacing(Pango.SCALE * 3) layout.set_spacing(Pango.SCALE * 3)
@ -304,10 +306,12 @@ class NotificationOverlayWindow(OverlayWindow):
# The window is full-screen regardless of what the user has selected. # The window is full-screen regardless of what the user has selected.
# We need to set a clip and a transform to imitate original behaviour # We need to set a clip and a transform to imitate original behaviour
# Used in wlroots & gamescope # Used in wlroots & gamescope
width = self.width (floating_x, floating_y, floating_width,
height = self.height floating_height) = self.get_floating_coords()
context.translate(self.pos_x, self.pos_y) if self.floating:
context.rectangle(0, 0, width, height) context.new_path()
context.translate(floating_x, floating_y)
context.rectangle(0, 0, floating_width, floating_height)
context.clip() context.clip()
current_y = height current_y = height
@ -367,7 +371,9 @@ class NotificationOverlayWindow(OverlayWindow):
layout.set_markup(text, -1) layout.set_markup(text, -1)
attr = layout.get_attributes() attr = layout.get_attributes()
width = self.limit_width if self.width > self.limit_width else self.width (floating_x, floating_y, floating_width,
floating_height) = self.get_floating_coords()
width = self.limit_width if floating_width > self.limit_width else floating_width
layout.set_width((Pango.SCALE * (width - layout.set_width((Pango.SCALE * (width -
(self.border_radius * 4 + icon_width + icon_pad)))) (self.border_radius * 4 + icon_width + icon_pad))))
layout.set_spacing(Pango.SCALE * 3) layout.set_spacing(Pango.SCALE * 3)
@ -388,7 +394,7 @@ class NotificationOverlayWindow(OverlayWindow):
left = 0 left = 0
if self.align_right: if self.align_right:
left = self.width - shape_width left = floating_width - shape_width
self.context.save() self.context.save()
# Draw Background # Draw Background

View file

@ -222,10 +222,20 @@ class OverlayWindow(Gtk.Window):
""" """
Set if the window is floating and what dimensions to use Set if the window is floating and what dimensions to use
""" """
if width > 1.0 and height > 1.0:
# Old data.
(screen_x, screen_y, screen_width,
screen_height) = self.get_display_coords()
pos_x = float(pos_x) / screen_width
pos_y = float(pos_y) / screen_height
width = float(width) / screen_width
height = float(height) / screen_height
if self.floating != floating or self.pos_x != pos_x or self.pos_y != pos_y or self.width != width or self.height != height: if self.floating != floating or self.pos_x != pos_x or self.pos_y != pos_y or self.width != width or self.height != height:
# Special case for Cinnamon desktop : see https://github.com/trigg/Discover/issues/322 # Special case for Cinnamon desktop : see https://github.com/trigg/Discover/issues/322
if 'XDG_SESSION_DESKTOP' in os.environ and os.environ['XDG_SESSION_DESKTOP'] == 'cinnamon': if 'XDG_SESSION_DESKTOP' in os.environ and os.environ['XDG_SESSION_DESKTOP'] == 'cinnamon':
floating = True floating = True
self.floating = floating self.floating = floating
self.pos_x = pos_x self.pos_x = pos_x
self.pos_y = pos_y self.pos_y = pos_y
@ -272,46 +282,48 @@ class OverlayWindow(Gtk.Window):
On Gamescope enforce size of display but only if it's the primary overlay On Gamescope enforce size of display but only if it's the primary overlay
""" """
if self.discover.steamos and not self.piggyback_parent: if self.discover.steamos and not self.piggyback_parent:
display = Gdk.Display.get_default() (floating_x, floating_y, floating_width,
if "get_monitor" in dir(display): floating_height) = self.get_floating_coords()
monitor = display.get_monitor(self.monitor) self.resize(floating_width, floating_height)
if monitor:
geometry = monitor.get_geometry()
scale_factor = monitor.get_scale_factor()
width = geometry.width
height = geometry.height
self.resize(width, height)
self.set_needs_redraw() self.set_needs_redraw()
return return
if not self.is_wayland: if not self.is_wayland:
self.set_decorated(False) self.set_decorated(False)
self.set_keep_above(True) self.set_keep_above(True)
(floating_x, floating_y, floating_width,
floating_height) = self.get_floating_coords()
self.resize(floating_width, floating_height)
self.move(floating_x, floating_y)
self.set_needs_redraw()
def get_display_coords(self):
if self.piggyback_parent:
return self.piggyback_parent.get_display_coords()
display = Gdk.Display.get_default() display = Gdk.Display.get_default()
if "get_monitor" in dir(display): if "get_monitor" in dir(display):
if self.monitor == None or self.monitor < 0:
monitor = display.get_monitor(0)
else:
monitor = display.get_monitor(self.monitor) monitor = display.get_monitor(self.monitor)
if monitor: if monitor:
geometry = monitor.get_geometry() geometry = monitor.get_geometry()
scale_factor = monitor.get_scale_factor() return (geometry.x, geometry.y, geometry.width, geometry.height)
if not self.floating: log.warn("No monitor found! This is going to go badly")
width = geometry.width return (0, 0, 1920, 1080) # We're in trouble
height = geometry.height
pos_x = geometry.x
pos_y = geometry.y
self.resize(width, height)
self.move(pos_x, pos_y)
else:
self.move(self.pos_x, self.pos_y)
self.resize(self.width, self.height)
else:
if self.floating:
self.move(self.pos_x, self.pos_y)
self.resize(self.width, self.height)
if not self.floating: def get_floating_coords(self):
(width, height) = self.get_size() (screen_x, screen_y, screen_width, screen_height) = self.get_display_coords()
self.width = width if self.floating:
self.height = height if self.pos_x == None or self.pos_y == None or self.width == None or self.height == None:
self.set_needs_redraw() log.error("No usable floating position")
if not self.is_wayland:
return (screen_x + self.pos_x * screen_width, screen_y + self.pos_y * screen_height, self.width * screen_width, self.height * screen_height)
return (self.pos_x * screen_width, self.pos_y * screen_height, self.width * screen_width, self.height * screen_height)
else:
return (0, 0, screen_width, screen_height)
def set_needs_redraw(self, be_pushy=False): def set_needs_redraw(self, be_pushy=False):
if (not self.hidden and self.enabled) or be_pushy: if (not self.hidden and self.enabled) or be_pushy:
@ -338,10 +350,6 @@ class OverlayWindow(Gtk.Window):
if self.piggyback_parent: if self.piggyback_parent:
self.piggyback_parent.redraw() self.piggyback_parent.redraw()
return return
if not self.floating:
(width, height) = self.get_size()
self.width = width
self.height = height
if gdkwin: if gdkwin:
compositing = self.get_screen().is_composited() compositing = self.get_screen().is_composited()
if not compositing or self.force_xshape: if not compositing or self.force_xshape:

View file

@ -326,10 +326,18 @@ class MainSettingsWindow():
t = self.widget['text_monitor'] t = self.widget['text_monitor']
m = self.widget['notification_monitor'] m = self.widget['notification_monitor']
v_value = v.get_active()
t_value = t.get_active()
m_value = m.get_active()
v.remove_all() v.remove_all()
t.remove_all() t.remove_all()
m.remove_all() m.remove_all()
v.append_text("Any")
t.append_text("Any")
m.append_text("Any")
display = Gdk.Display.get_default() display = Gdk.Display.get_default()
if "get_n_monitors" in dir(display): if "get_n_monitors" in dir(display):
for i in range(0, display.get_n_monitors()): for i in range(0, display.get_n_monitors()):
@ -337,6 +345,10 @@ class MainSettingsWindow():
t.append_text(display.get_monitor(i).get_model()) t.append_text(display.get_monitor(i).get_model())
m.append_text(display.get_monitor(i).get_model()) m.append_text(display.get_monitor(i).get_model())
v.set_active(v_value)
t.set_active(t_value)
m.set_active(m_value)
def close_window(self, widget=None, event=None): def close_window(self, widget=None, event=None):
""" """
Hide the settings window for use at a later date Hide the settings window for use at a later date
@ -396,11 +408,13 @@ class MainSettingsWindow():
# Read Voice section # Read Voice section
self.voice_floating_x = config.getint("main", "floating_x", fallback=0) self.voice_floating_x = config.getfloat(
self.voice_floating_y = config.getint("main", "floating_y", fallback=0) "main", "floating_x", fallback=0)
self.voice_floating_w = config.getint( self.voice_floating_y = config.getfloat(
"main", "floating_y", fallback=0)
self.voice_floating_w = config.getfloat(
"main", "floating_w", fallback=400) "main", "floating_w", fallback=400)
self.voice_floating_h = config.getint( self.voice_floating_h = config.getfloat(
"main", "floating_h", fallback=400) "main", "floating_h", fallback=400)
self.widget['voice_anchor_float'].set_active( self.widget['voice_anchor_float'].set_active(
@ -418,7 +432,7 @@ class MainSettingsWindow():
except: except:
pass pass
self.widget['voice_monitor'].set_active(monitor) self.widget['voice_monitor'].set_active(monitor+1)
font = config.get("main", "font", fallback=None) font = config.get("main", "font", fallback=None)
if font: if font:
@ -551,11 +565,13 @@ class MainSettingsWindow():
# Read Text section # Read Text section
self.text_floating_x = config.getint("text", "floating_x", fallback=0) self.text_floating_x = config.getfloat(
self.text_floating_y = config.getint("text", "floating_y", fallback=0) "text", "floating_x", fallback=0)
self.text_floating_w = config.getint( self.text_floating_y = config.getfloat(
"text", "floating_y", fallback=0)
self.text_floating_w = config.getfloat(
"text", "floating_w", fallback=400) "text", "floating_w", fallback=400)
self.text_floating_h = config.getint( self.text_floating_h = config.getfloat(
"text", "floating_h", fallback=400) "text", "floating_h", fallback=400)
self.widget['text_enable'].set_active( self.widget['text_enable'].set_active(
@ -588,7 +604,7 @@ class MainSettingsWindow():
except: except:
pass pass
self.widget['text_monitor'].set_active(monitor) self.widget['text_monitor'].set_active(monitor+1)
self.widget['text_show_attachments'].set_active(config.getboolean( self.widget['text_show_attachments'].set_active(config.getboolean(
"text", "show_attach", fallback=True)) "text", "show_attach", fallback=True))
@ -631,7 +647,7 @@ class MainSettingsWindow():
except: except:
pass pass
self.widget['notification_monitor'].set_active(monitor) self.widget['notification_monitor'].set_active(monitor+1)
self.widget['notification_align_1'].set_active(config.getboolean( self.widget['notification_align_1'].set_active(config.getboolean(
"notification", "rightalign", fallback=True)) "notification", "rightalign", fallback=True))
@ -831,14 +847,14 @@ class MainSettingsWindow():
config.read(self.config_file) config.read(self.config_file)
if not "main" in config.sections(): if not "main" in config.sections():
config.add_section("main") config.add_section("main")
config.set("main", "floating_x", "%s" % config.set("main", "floating_x", "%f" %
(int(self.voice_floating_x))) (self.voice_floating_x))
config.set("main", "floating_y", "%s" % config.set("main", "floating_y", "%f" %
(int(self.voice_floating_y))) (self.voice_floating_y))
config.set("main", "floating_w", "%s" % config.set("main", "floating_w", "%f" %
(int(self.voice_floating_w))) (self.voice_floating_w))
config.set("main", "floating_h", "%s" % config.set("main", "floating_h", "%f" %
(int(self.voice_floating_h))) (self.voice_floating_h))
with open(self.config_file, 'w') as file: with open(self.config_file, 'w') as file:
config.write(file) config.write(file)
@ -857,12 +873,12 @@ class MainSettingsWindow():
width=self.voice_floating_w, height=self.voice_floating_h, width=self.voice_floating_w, height=self.voice_floating_h,
message=_("Place & resize this window then press Green!"), settings=self, message=_("Place & resize this window then press Green!"), settings=self,
steamos=self.steamos, steamos=self.steamos,
monitor=self.get_monitor_obj(self.widget['voice_monitor'].get_active())) monitor=self.widget['voice_monitor'].get_active()-1)
else: else:
self.voice_placement_window = DraggableWindow( self.voice_placement_window = DraggableWindow(
pos_x=self.voice_floating_x, pos_y=self.voice_floating_y, pos_x=self.voice_floating_x, pos_y=self.voice_floating_y,
width=self.voice_floating_w, height=self.voice_floating_h, width=self.voice_floating_w, height=self.voice_floating_h,
message=_("Place & resize this window then press Save!"), settings=self) message=_("Place & resize this window then press Save!"), settings=self, monitor=self.widget['voice_monitor'].get_active()-1)
if button: if button:
button.set_label(_("Save this position")) button.set_label(_("Save this position"))
@ -878,14 +894,14 @@ class MainSettingsWindow():
config.read(self.config_file) config.read(self.config_file)
if not "text" in config.sections(): if not "text" in config.sections():
config.add_section("text") config.add_section("text")
config.set("text", "floating_x", "%s" % config.set("text", "floating_x", "%f" %
(int(self.text_floating_x))) (self.text_floating_x))
config.set("text", "floating_y", "%s" % config.set("text", "floating_y", "%f" %
(int(self.text_floating_y))) (self.text_floating_y))
config.set("text", "floating_w", "%s" % config.set("text", "floating_w", "%f" %
(int(self.text_floating_w))) (self.text_floating_w))
config.set("text", "floating_h", "%s" % config.set("text", "floating_h", "%f" %
(int(self.text_floating_h))) (self.text_floating_h))
with open(self.config_file, 'w') as file: with open(self.config_file, 'w') as file:
config.write(file) config.write(file)
@ -904,12 +920,12 @@ class MainSettingsWindow():
width=self.text_floating_w, height=self.text_floating_h, width=self.text_floating_w, height=self.text_floating_h,
message=_("Place & resize this window then press Green!"), settings=self, message=_("Place & resize this window then press Green!"), settings=self,
steamos=self.steamos, steamos=self.steamos,
monitor=self.get_monitor_obj(self.widget['text_monitor'].get_active())) monitor=self.widget['text_monitor'].get_active()-1)
else: else:
self.text_placement_window = DraggableWindow( self.text_placement_window = DraggableWindow(
pos_x=self.text_floating_x, pos_y=self.text_floating_y, pos_x=self.text_floating_x, pos_y=self.text_floating_y,
width=self.text_floating_w, height=self.text_floating_h, width=self.text_floating_w, height=self.text_floating_h,
message=_("Place & resize this window then press Save!"), settings=self) message=_("Place & resize this window then press Save!"), settings=self, monitor=self.widget['text_monitor'].get_active()-1)
if button: if button:
button.set_label(_("Save this position")) button.set_label(_("Save this position"))
@ -962,7 +978,7 @@ class MainSettingsWindow():
self.widget['voice_place_window_button'].hide() self.widget['voice_place_window_button'].hide()
def voice_monitor_changed(self, button): def voice_monitor_changed(self, button):
self.config_set("main", "monitor", "%s" % (button.get_active())) self.config_set("main", "monitor", "%s" % (button.get_active()-1))
def voice_align_1_changed(self, button): def voice_align_1_changed(self, button):
self.config_set("main", "rightalign", "%s" % (button.get_active())) self.config_set("main", "rightalign", "%s" % (button.get_active()))
@ -1179,7 +1195,7 @@ class MainSettingsWindow():
self.config_set("text", "bg_col", json.dumps(colour)) self.config_set("text", "bg_col", json.dumps(colour))
def text_monitor_changed(self, button): def text_monitor_changed(self, button):
self.config_set("text", "monitor", "%s" % (button.get_active())) self.config_set("text", "monitor", "%s" % (button.get_active()-1))
def text_show_attachments_changed(self, button): def text_show_attachments_changed(self, button):
self.config_set("text", "show_attach", "%s" % (button.get_active())) self.config_set("text", "show_attach", "%s" % (button.get_active()))
@ -1217,7 +1233,7 @@ class MainSettingsWindow():
def notification_monitor_changed(self, button): def notification_monitor_changed(self, button):
self.config_set("notification", "monitor", "%s" % self.config_set("notification", "monitor", "%s" %
(button.get_active())) (button.get_active()-1))
def notification_align_1_changed(self, button): def notification_align_1_changed(self, button):
self.config_set("notification", "rightalign", "%s" % self.config_set("notification", "rightalign", "%s" %

View file

@ -227,13 +227,17 @@ class TextOverlayWindow(OverlayWindow):
# The window is full-screen regardless of what the user has selected. # The window is full-screen regardless of what the user has selected.
# We need to set a clip and a transform to imitate original behaviour # We need to set a clip and a transform to imitate original behaviour
# Used in wlroots & gamescope # Used in wlroots & gamescope
width = self.width (floating_x, floating_y, floating_width,
height = self.height floating_height) = self.get_floating_coords()
context.translate(self.pos_x, self.pos_y) if self.floating:
context.rectangle(0, 0, width, height) context.new_path()
context.translate(floating_x, floating_y)
context.rectangle(0, 0, floating_width, floating_height)
context.clip() context.clip()
pass
current_y = height (floating_x, floating_y, floating_width,
floating_height) = self.get_floating_coords()
current_y = floating_height
tnow = time.time() tnow = time.time()
for line in reversed(self.content): for line in reversed(self.content):
if self.popup_style and tnow - line['time'] > self.text_time: if self.popup_style and tnow - line['time'] > self.text_time:
@ -278,15 +282,17 @@ class TextOverlayWindow(OverlayWindow):
""" """
Draw an attachment Draw an attachment
""" """
(floating_x, floating_y, floating_width,
floating_height) = self.get_floating_coords()
if url in self.attachment and self.attachment[url]: if url in self.attachment and self.attachment[url]:
pix = self.attachment[url] pix = self.attachment[url]
image_width = min(pix.get_width(), self.width) image_width = min(pix.get_width(), floating_width)
image_height = min(pix.get_height(), (self.height * .7)) image_height = min(pix.get_height(), (floating_height * .7))
(_ax, _ay, _aw, aspect_height) = get_aspected_size( (_ax, _ay, _aw, aspect_height) = get_aspected_size(
pix, image_width, image_height) pix, image_width, image_height)
self.col(self.bg_col) self.col(self.bg_col)
self.context.rectangle(0, pos_y - aspect_height, self.context.rectangle(0, pos_y - aspect_height,
self.width, aspect_height) floating_width, aspect_height)
self.context.fill() self.context.fill()
self.context.set_operator(cairo.OPERATOR_OVER) self.context.set_operator(cairo.OPERATOR_OVER)
@ -304,14 +310,17 @@ class TextOverlayWindow(OverlayWindow):
layout.set_markup(text, -1) layout.set_markup(text, -1)
attr = layout.get_attributes() attr = layout.get_attributes()
layout.set_width(Pango.SCALE * self.width) (floating_x, floating_y, floating_width,
floating_height) = self.get_floating_coords()
layout.set_width(Pango.SCALE * floating_width)
layout.set_spacing(Pango.SCALE * 3) layout.set_spacing(Pango.SCALE * 3)
if self.text_font: if self.text_font:
font = Pango.FontDescription(self.text_font) font = Pango.FontDescription(self.text_font)
layout.set_font_description(font) layout.set_font_description(font)
_tw, text_height = layout.get_pixel_size() _tw, text_height = layout.get_pixel_size()
self.col(self.bg_col) self.col(self.bg_col)
self.context.rectangle(0, pos_y - text_height, self.width, text_height) self.context.rectangle(0, pos_y - text_height,
floating_width, text_height)
self.context.fill() self.context.fill()
self.context.set_operator(cairo.OPERATOR_OVER) self.context.set_operator(cairo.OPERATOR_OVER)
self.col(self.fg_col) self.col(self.fg_col)

View file

@ -551,17 +551,18 @@ class VoiceOverlayWindow(OverlayWindow):
context.save() context.save()
if self.piggyback: if self.piggyback:
self.piggyback.overlay_draw(w, context, data) self.piggyback.overlay_draw(w, context, data)
(floating_x, floating_y, floating_width,
floating_height) = self.get_floating_coords()
if self.is_wayland or self.piggyback_parent or self.discover.steamos: if self.is_wayland or self.piggyback_parent or self.discover.steamos:
# Special case! # Special case!
# The window is full-screen regardless of what the user has selected. # The window is full-screen regardless of what the user has selected.
# We need to set a clip and a transform to imitate original behaviour # We need to set a clip and a transform to imitate original behaviour
# Used in wlroots & gamescope # Used in wlroots & gamescope
width = self.width
height = self.height
if self.floating: if self.floating:
context.new_path() context.new_path()
context.translate(self.pos_x, self.pos_y) context.translate(floating_x, floating_y)
context.rectangle(0, 0, width, height) context.rectangle(0, 0, floating_width, floating_height)
context.clip() context.clip()
context.set_operator(cairo.OPERATOR_OVER) context.set_operator(cairo.OPERATOR_OVER)
@ -699,7 +700,7 @@ class VoiceOverlayWindow(OverlayWindow):
offset_x = avatar_size + self.horz_edge_padding offset_x = avatar_size + self.horz_edge_padding
if self.align_right: if self.align_right:
offset_x_mult = -1 offset_x_mult = -1
current_x = self.width - avatar_size - self.horz_edge_padding current_x = floating_width - avatar_size - self.horz_edge_padding
# Choose where to start drawing # Choose where to start drawing
current_y = 0 + self.vert_edge_padding current_y = 0 + self.vert_edge_padding
@ -917,8 +918,9 @@ class VoiceOverlayWindow(OverlayWindow):
layout = self.create_pango_layout(string) layout = self.create_pango_layout(string)
layout.set_auto_dir(True) layout.set_auto_dir(True)
layout.set_markup(string, -1) layout.set_markup(string, -1)
(floating_x, floating_y, floating_width,
layout.set_width(Pango.SCALE * self.width) floating_height) = self.get_floating_coords()
layout.set_width(Pango.SCALE * floating_width)
layout.set_spacing(Pango.SCALE * 3) layout.set_spacing(Pango.SCALE * 3)
if font: if font:
font = Pango.FontDescription(font) font = Pango.FontDescription(font)