- Heavy refactor
- - Rename unused vars with _ or removed - - Remove unused sections of code - - Change name collisions with Gtk/bultins - Bumped internal version to 0.3.0 in prep
This commit is contained in:
parent
060fc11818
commit
39b1a19e3c
16 changed files with 436 additions and 276 deletions
|
|
@ -1 +1,14 @@
|
|||
# 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 3 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, see <https://www.gnu.org/licenses/>.
|
||||
"""Entry point for Discover Overlay"""
|
||||
from .discover_overlay import *
|
||||
|
|
|
|||
|
|
@ -1,4 +1,16 @@
|
|||
import sys
|
||||
# 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 3 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, see <https://www.gnu.org/licenses/>.
|
||||
"""A class to assist auto-start"""
|
||||
import os
|
||||
import logging
|
||||
try:
|
||||
|
|
@ -9,6 +21,8 @@ except ModuleNotFoundError:
|
|||
|
||||
|
||||
class Autostart:
|
||||
"""A class to assist auto-start"""
|
||||
|
||||
def __init__(self, app_name):
|
||||
if not app_name.endswith(".desktop"):
|
||||
app_name = "%s.desktop" % (app_name)
|
||||
|
|
@ -19,35 +33,37 @@ class Autostart:
|
|||
xdg_data_home, 'applications/'), '/usr/share/applications/']
|
||||
self.auto = self.find_auto()
|
||||
self.desktop = self.find_desktop()
|
||||
logging.info("Autostart info : desktop %s auto %s" %
|
||||
(self.desktop, self.auto))
|
||||
logging.info("Autostart info : desktop %s auto %s",
|
||||
self.desktop, self.auto)
|
||||
|
||||
def find_auto(self):
|
||||
for p in self.auto_locations:
|
||||
file = os.path.join(p, self.app_name)
|
||||
"""Check all known locations for auto-started apps"""
|
||||
for path in self.auto_locations:
|
||||
file = os.path.join(path, self.app_name)
|
||||
if os.path.exists(file):
|
||||
return file
|
||||
return None
|
||||
|
||||
def find_desktop(self):
|
||||
for p in self.desktop_locations:
|
||||
file = os.path.join(p, self.app_name)
|
||||
"""Check all known locations for desktop apps"""
|
||||
for path in self.desktop_locations:
|
||||
file = os.path.join(path, self.app_name)
|
||||
if os.path.exists(file):
|
||||
return file
|
||||
return None
|
||||
|
||||
def set_autostart(self, b):
|
||||
if b and not self.auto:
|
||||
def set_autostart(self, enable):
|
||||
"""Set or Unset auto-start state"""
|
||||
if enable and not self.auto:
|
||||
# Enable
|
||||
d = os.path.join(xdg_config_home, 'autostart')
|
||||
self.auto = os.path.join(d, self.app_name)
|
||||
directory = os.path.join(xdg_config_home, 'autostart')
|
||||
self.auto = os.path.join(directory, self.app_name)
|
||||
os.symlink(self.desktop, self.auto)
|
||||
pass
|
||||
elif not b and self.auto:
|
||||
elif not enable and self.auto:
|
||||
# Disable
|
||||
if os.path.islink(self.auto):
|
||||
os.remove(self.auto)
|
||||
pass
|
||||
|
||||
def is_auto(self):
|
||||
"""Check if it's already set to auto-start"""
|
||||
return True if self.auto else False
|
||||
|
|
|
|||
|
|
@ -1,12 +1,23 @@
|
|||
import websocket
|
||||
# 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 3 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, see <https://www.gnu.org/licenses/>.
|
||||
import select
|
||||
import time
|
||||
import json
|
||||
import re
|
||||
import sys
|
||||
import requests
|
||||
import logging
|
||||
import calendar
|
||||
import websocket
|
||||
import requests
|
||||
|
||||
|
||||
class DiscordConnector:
|
||||
|
|
@ -17,7 +28,6 @@ class DiscordConnector:
|
|||
self.voice_overlay = voice_overlay
|
||||
self.ws = None
|
||||
self.access_token = "none"
|
||||
# TODO Magic number
|
||||
self.oauth_token = "207646673902501888"
|
||||
self.access_delay = 0
|
||||
self.warn_connection = True
|
||||
|
|
@ -47,7 +57,7 @@ class DiscordConnector:
|
|||
x = requests.post(url, json=myobj)
|
||||
try:
|
||||
j = json.loads(x.text)
|
||||
except:
|
||||
except json.JSONDecodeError:
|
||||
j = {}
|
||||
if "access_token" in j:
|
||||
self.access_token = j["access_token"]
|
||||
|
|
@ -62,7 +72,7 @@ class DiscordConnector:
|
|||
if channel != self.current_voice:
|
||||
cn = self.channels[channel]['name']
|
||||
logging.info(
|
||||
"Joined room: %s" % (cn))
|
||||
"Joined room: %s", cn)
|
||||
self.sub_voice_channel(channel)
|
||||
self.current_voice = channel
|
||||
if need_req:
|
||||
|
|
@ -75,7 +85,7 @@ class DiscordConnector:
|
|||
if channel != self.current_text:
|
||||
self.current_text = channel
|
||||
logging.info(
|
||||
"Changing text room: %s" % (channel))
|
||||
"Changing text room: %s", channel)
|
||||
if need_req:
|
||||
self.req_channel_details(channel)
|
||||
|
||||
|
|
@ -203,8 +213,6 @@ class DiscordConnector:
|
|||
if j["data"]["user"]["id"] == self.user["id"]:
|
||||
self.in_room = []
|
||||
# self.sub_all_voice()
|
||||
else:
|
||||
un = j["data"]["user"]["username"]
|
||||
elif j["evt"] == "SPEAKING_START":
|
||||
self.list_altered = True
|
||||
# It's only possible to get alerts for the room you're in
|
||||
|
|
@ -245,9 +253,9 @@ class DiscordConnector:
|
|||
self.req_guilds()
|
||||
self.user = j["data"]["user"]
|
||||
logging.info(
|
||||
"ID is %s" % (self.user["id"]))
|
||||
"ID is %s", self.user["id"])
|
||||
logging.info(
|
||||
"Logged in as %s" % (self.user["username"]))
|
||||
"Logged in as %s", self.user["username"])
|
||||
self.authed = True
|
||||
return
|
||||
elif j["cmd"] == "GET_GUILDS":
|
||||
|
|
@ -307,14 +315,14 @@ class DiscordConnector:
|
|||
for channel in guild["channels"]:
|
||||
channels = channels + " " + channel["name"]
|
||||
logging.info(
|
||||
u"%s: %s" % (guild["name"], channels))
|
||||
u"%s: %s", guild["name"], channels)
|
||||
self.sub_server()
|
||||
self.find_user()
|
||||
if self.last_text_channel:
|
||||
self.sub_text_channel(self.last_text_channel)
|
||||
|
||||
def on_error(self, error):
|
||||
logging.error("ERROR : %s" % (error))
|
||||
logging.error("ERROR : %s", error)
|
||||
|
||||
def on_close(self):
|
||||
logging.info("Connection closed")
|
||||
|
|
@ -341,7 +349,7 @@ class DiscordConnector:
|
|||
if self.channels[channel]["type"] == 2:
|
||||
self.req_channel_details(channel)
|
||||
count += 1
|
||||
logging.warn("Getting %s rooms" %(count))
|
||||
logging.warning("Getting %s rooms", count)
|
||||
|
||||
def sub_raw(self, cmd, channel, nonce):
|
||||
self.ws.send("{\"cmd\":\"SUBSCRIBE\",\"args\":{%s},\"evt\":\"%s\",\"nonce\":\"%s\"}" % (
|
||||
|
|
@ -424,14 +432,14 @@ class DiscordConnector:
|
|||
self.set_text_channel(self.text_settings.get_channel())
|
||||
|
||||
# Poll socket for new information
|
||||
r, w, e = select.select((self.ws.sock,), (), (), 0)
|
||||
r, _w, _e = select.select((self.ws.sock,), (), (), 0)
|
||||
while r:
|
||||
try:
|
||||
# Recieve & send to on_message
|
||||
msg = self.ws.recv()
|
||||
self.on_message(msg)
|
||||
r, w, e = select.select((self.ws.sock,), (), (), 0)
|
||||
except websocket._exceptions.WebSocketConnectionClosedException:
|
||||
r, _w, _e = select.select((self.ws.sock,), (), (), 0)
|
||||
except websocket.WebSocketConnectionClosedException:
|
||||
self.on_close()
|
||||
return True
|
||||
return True
|
||||
|
|
@ -448,8 +456,7 @@ class DiscordConnector:
|
|||
try:
|
||||
self.ws = websocket.create_connection("ws://127.0.0.1:6463/?v=1&client_id=%s" % (self.oauth_token),
|
||||
origin="https://streamkit.discord.com")
|
||||
except Exception as e:
|
||||
except ConnectionError as e:
|
||||
if self.error_connection:
|
||||
logging.error(e)
|
||||
self.error_connection = False
|
||||
pass
|
||||
|
|
|
|||
|
|
@ -10,18 +10,18 @@
|
|||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
import os
|
||||
import sys
|
||||
import gi
|
||||
gi.require_version("Gtk", "3.0")
|
||||
from gi.repository import Gtk, GLib, Gio
|
||||
import select
|
||||
import logging
|
||||
import pidfile
|
||||
from .settings_window import MainSettingsWindow
|
||||
from .voice_overlay import VoiceOverlayWindow
|
||||
from .text_overlay import TextOverlayWindow
|
||||
from .discord_connector import DiscordConnector
|
||||
import logging
|
||||
import pidfile
|
||||
import os
|
||||
import sys
|
||||
gi.require_version("Gtk", "3.0")
|
||||
# pylint: disable=wrong-import-position
|
||||
from gi.repository import Gtk, GLib, Gio
|
||||
|
||||
try:
|
||||
from xdg.BaseDirectory import xdg_config_home
|
||||
|
|
@ -31,6 +31,9 @@ except ModuleNotFoundError:
|
|||
|
||||
class Discover:
|
||||
def __init__(self, rpc_file, args):
|
||||
self.ind = None
|
||||
self.tray = None
|
||||
|
||||
self.create_gui()
|
||||
self.connection = DiscordConnector(
|
||||
self.settings.text_settings, self.settings.voice_settings,
|
||||
|
|
@ -44,10 +47,7 @@ class Discover:
|
|||
monitor.connect("changed", self.rpc_changed)
|
||||
self.do_args(args)
|
||||
|
||||
try:
|
||||
Gtk.main()
|
||||
except:
|
||||
pass
|
||||
|
||||
def do_args(self, data):
|
||||
if "--help" in data:
|
||||
|
|
@ -59,8 +59,7 @@ class Discover:
|
|||
elif "--close" in data:
|
||||
sys.exit(0)
|
||||
|
||||
|
||||
def rpc_changed(self, a=None, b=None, c=None,d=None):
|
||||
def rpc_changed(self, _a=None, _b=None, _c=None, _d=None):
|
||||
with open(self.rpc_file, "r") as tfile:
|
||||
data = tfile.readlines()
|
||||
if len(data) >= 1:
|
||||
|
|
@ -71,12 +70,14 @@ class Discover:
|
|||
self.text_overlay = TextOverlayWindow(self)
|
||||
self.menu = self.make_menu()
|
||||
self.make_sys_tray_icon(self.menu)
|
||||
self.settings = MainSettingsWindow(self.text_overlay, self.voice_overlay)
|
||||
self.settings = MainSettingsWindow(
|
||||
self.text_overlay, self.voice_overlay)
|
||||
|
||||
def make_sys_tray_icon(self, menu):
|
||||
# Create AppIndicator
|
||||
try:
|
||||
gi.require_version('AppIndicator3', '0.1')
|
||||
# pylint: disable=import-outside-toplevel
|
||||
from gi.repository import AppIndicator3
|
||||
self.ind = AppIndicator3.Indicator.new(
|
||||
"discover_overlay",
|
||||
|
|
@ -84,9 +85,9 @@ class Discover:
|
|||
AppIndicator3.IndicatorCategory.APPLICATION_STATUS)
|
||||
self.ind.set_status(AppIndicator3.IndicatorStatus.ACTIVE)
|
||||
self.ind.set_menu(menu)
|
||||
except Exception as e:
|
||||
except ImportError as exception:
|
||||
# Create System Tray
|
||||
logging.info("Falling back to Systray : %s" % (e))
|
||||
logging.info("Falling back to Systray : %s", exception)
|
||||
self.tray = Gtk.StatusIcon.new_from_icon_name("discover-overlay")
|
||||
self.tray.connect('popup-menu', self.show_menu)
|
||||
|
||||
|
|
@ -109,10 +110,10 @@ class Discover:
|
|||
self.menu.popup(
|
||||
None, None, Gtk.StatusIcon.position_menu, obj, button, time)
|
||||
|
||||
def show_settings(self, obj=None, data=None):
|
||||
self.settings.present()
|
||||
def show_settings(self, _obj=None, _data=None):
|
||||
self.settings.present_settings()
|
||||
|
||||
def close(self, a=None, b=None, c=None):
|
||||
def close(self, _a=None, _b=None, _c=None):
|
||||
Gtk.main_quit()
|
||||
|
||||
|
||||
|
|
@ -129,9 +130,8 @@ def entrypoint():
|
|||
logging.getLogger().setLevel(logging.INFO)
|
||||
Discover(rpc_file, line)
|
||||
except pidfile.AlreadyRunningError:
|
||||
logging.warn("Discover overlay is currently running")
|
||||
logging.warning("Discover overlay is currently running")
|
||||
|
||||
with open(rpc_file, "w") as tfile:
|
||||
tfile.write(line)
|
||||
logging.warn("Sent RPC command")
|
||||
|
||||
logging.warning("Sent RPC command")
|
||||
|
|
|
|||
|
|
@ -1,11 +1,26 @@
|
|||
# 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 3 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, see <https://www.gnu.org/licenses/>.
|
||||
"""An X11 window which can be moved and resized"""
|
||||
import gi
|
||||
gi.require_version("Gtk", "3.0")
|
||||
import cairo
|
||||
gi.require_version("Gtk", "3.0")
|
||||
# pylint: disable=wrong-import-position
|
||||
from gi.repository import Gtk, Gdk
|
||||
import logging
|
||||
|
||||
|
||||
class DraggableWindow(Gtk.Window):
|
||||
"""An X11 window which can be moved and resized"""
|
||||
|
||||
def __init__(self, x=0, y=0, w=300, h=300, message="Message", settings=None):
|
||||
Gtk.Window.__init__(self, type=Gtk.WindowType.POPUP)
|
||||
if w < 100:
|
||||
|
|
@ -20,7 +35,7 @@ class DraggableWindow(Gtk.Window):
|
|||
self.message = message
|
||||
self.set_size_request(50, 50)
|
||||
|
||||
self.connect('draw', self.draw)
|
||||
self.connect('draw', self.dodraw)
|
||||
self.connect('motion-notify-event', self.drag)
|
||||
self.connect('button-press-event', self.button_press)
|
||||
self.connect('button-release-event', self.button_release)
|
||||
|
|
@ -45,28 +60,15 @@ class DraggableWindow(Gtk.Window):
|
|||
self.show_all()
|
||||
|
||||
def force_location(self):
|
||||
"""Move the window to previously given co-ords. Also double check sanity on layer & decorations"""
|
||||
|
||||
self.set_decorated(False)
|
||||
self.set_keep_above(True)
|
||||
display = Gdk.Display.get_default()
|
||||
if "get_monitor" in dir(display):
|
||||
monitor = display.get_monitor(self.monitor)
|
||||
geometry = monitor.get_geometry()
|
||||
scale_factor = monitor.get_scale_factor()
|
||||
w = scale_factor * geometry.width
|
||||
h = scale_factor * geometry.height
|
||||
x = geometry.x
|
||||
y = geometry.y
|
||||
else:
|
||||
screen = display.get_default_screen()
|
||||
w = screen.width()
|
||||
h = screen.height()
|
||||
x = 0
|
||||
y = 0
|
||||
#self.resize(400, h)
|
||||
self.move(self.x, self.y)
|
||||
self.resize(self.w, self.h)
|
||||
|
||||
def drag(self, w, event):
|
||||
def drag(self, _w, event):
|
||||
"""Called by GTK while mouse is moving over window. Used to resize and move"""
|
||||
if event.state & Gdk.ModifierType.BUTTON1_MASK:
|
||||
if self.drag_type == 1:
|
||||
# Center is move
|
||||
|
|
@ -92,6 +94,7 @@ class DraggableWindow(Gtk.Window):
|
|||
self.force_location()
|
||||
|
||||
def button_press(self, w, event):
|
||||
"""Called when a mouse button is pressed on this window"""
|
||||
(w, h) = self.get_size()
|
||||
if not self.drag_type:
|
||||
self.drag_type = 1
|
||||
|
|
@ -103,10 +106,12 @@ class DraggableWindow(Gtk.Window):
|
|||
self.drag_x = event.x
|
||||
self.drag_y = event.y
|
||||
|
||||
def button_release(self, w, event):
|
||||
def button_release(self, _w, _event):
|
||||
"""Called when a mouse button is released"""
|
||||
self.drag_type = None
|
||||
|
||||
def draw(self, widget, context):
|
||||
def dodraw(self, _widget, context):
|
||||
"""Draw our window."""
|
||||
context.set_source_rgba(1.0, 1.0, 0.0, 0.7)
|
||||
# Don't layer drawing over each other, always replace
|
||||
context.set_operator(cairo.OPERATOR_SOURCE)
|
||||
|
|
@ -117,7 +122,7 @@ class DraggableWindow(Gtk.Window):
|
|||
|
||||
# Draw text
|
||||
context.set_source_rgba(0.0, 0.0, 0.0, 1.0)
|
||||
xb, yb, w, h, dx, dy = context.text_extents(self.message)
|
||||
_xb, _yb, w, h, _dx, _dy = context.text_extents(self.message)
|
||||
context.move_to(sw / 2 - w / 2, sh / 2 - h / 2)
|
||||
context.show_text(self.message)
|
||||
|
||||
|
|
@ -130,6 +135,7 @@ class DraggableWindow(Gtk.Window):
|
|||
context.fill()
|
||||
|
||||
def get_coords(self):
|
||||
(x, y) = self.placement_window.get_position()
|
||||
(w, h) = self.placement_window.get_size()
|
||||
"""Return window position and size"""
|
||||
(x, y) = self.get_position()
|
||||
(w, h) = self.get_size()
|
||||
return (x, y, w, h)
|
||||
|
|
|
|||
|
|
@ -1,11 +1,26 @@
|
|||
# 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 3 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, see <https://www.gnu.org/licenses/>.
|
||||
"""A Wayland full-screen window which can be moved and resized"""
|
||||
import cairo
|
||||
import gi
|
||||
gi.require_version("Gtk", "3.0")
|
||||
import cairo
|
||||
# pylint: disable=wrong-import-position
|
||||
from gi.repository import Gtk, Gdk, GtkLayerShell
|
||||
import logging
|
||||
|
||||
|
||||
class DraggableWindowWayland(Gtk.Window):
|
||||
"""A Wayland full-screen window which can be moved and resized"""
|
||||
|
||||
def __init__(self, x=0, y=0, w=300, h=300, message="Message", settings=None):
|
||||
Gtk.Window.__init__(self, type=Gtk.WindowType.TOPLEVEL)
|
||||
if w < 100:
|
||||
|
|
@ -20,7 +35,7 @@ class DraggableWindowWayland(Gtk.Window):
|
|||
self.message = message
|
||||
self.set_size_request(50, 50)
|
||||
|
||||
self.connect('draw', self.draw)
|
||||
self.connect('draw', self.dodraw)
|
||||
self.connect('motion-notify-event', self.drag)
|
||||
self.connect('button-press-event', self.button_press)
|
||||
self.connect('button-release-event', self.button_release)
|
||||
|
|
@ -42,18 +57,20 @@ class DraggableWindowWayland(Gtk.Window):
|
|||
# self.force_location()
|
||||
|
||||
def force_location(self):
|
||||
(sx, sy)= self.get_size()
|
||||
"""Move the window to previously given co-ords. In wayland just clip to current screen"""
|
||||
(size_x, size_y) = self.get_size()
|
||||
if self.x < 0:
|
||||
self.x = 0
|
||||
if self.y < 0:
|
||||
self.y = 0
|
||||
if self.x + self.w > sx:
|
||||
self.x = sx - self.w
|
||||
if self.y + self.h > sy:
|
||||
self.y = sy - self.h
|
||||
if self.x + self.w > size_x:
|
||||
self.x = size_x - self.w
|
||||
if self.y + self.h > size_y:
|
||||
self.y = size_y - self.h
|
||||
self.queue_draw()
|
||||
|
||||
def drag(self, w, event):
|
||||
def drag(self, _w, event):
|
||||
"""Called by GTK while mouse is moving over window. Used to resize and move"""
|
||||
if event.state & Gdk.ModifierType.BUTTON1_MASK:
|
||||
if self.drag_type == 1:
|
||||
# Center is move
|
||||
|
|
@ -81,7 +98,8 @@ class DraggableWindowWayland(Gtk.Window):
|
|||
self.drag_y = event.y
|
||||
self.force_location()
|
||||
|
||||
def button_press(self, w, event):
|
||||
def button_press(self, _w, event):
|
||||
"""Called when a mouse button is pressed on this window"""
|
||||
px = event.x - self.x
|
||||
py = event.y - self.y
|
||||
|
||||
|
|
@ -97,10 +115,12 @@ class DraggableWindowWayland(Gtk.Window):
|
|||
self.drag_x = event.x
|
||||
self.drag_y = event.y
|
||||
|
||||
def button_release(self, w, event):
|
||||
def button_release(self, _w, _event):
|
||||
"""Called when a mouse button is released"""
|
||||
self.drag_type = None
|
||||
|
||||
def draw(self, widget, context):
|
||||
def dodraw(self, _widget, context):
|
||||
"""Draw our window. For wayland we're secretly a fullscreen app and need to draw only a single rectangle of the overlay"""
|
||||
context.translate(self.x, self.y)
|
||||
context.save()
|
||||
context.rectangle(0, 0, self.w, self.h)
|
||||
|
|
@ -114,8 +134,8 @@ class DraggableWindowWayland(Gtk.Window):
|
|||
|
||||
# Draw text
|
||||
context.set_source_rgba(0.0, 0.0, 0.0, 1.0)
|
||||
xb, yb, w, h, dx, dy = context.text_extents(self.message)
|
||||
context.move_to(self.w / 2 - w / 2, self.h / 2 - h / 2)
|
||||
_xb, _yb, width, height, _dx, _dy = context.text_extents(self.message)
|
||||
context.move_to(self.w / 2 - width / 2, self.h / 2 - height / 2)
|
||||
context.show_text(self.message)
|
||||
|
||||
# Draw resizing edges
|
||||
|
|
@ -132,6 +152,6 @@ class DraggableWindowWayland(Gtk.Window):
|
|||
context.fill()
|
||||
context.restore()
|
||||
|
||||
|
||||
def get_coords(self):
|
||||
"""Return the position and size of the window"""
|
||||
return (self.x, self.y, self.w, self.h)
|
||||
|
|
@ -1,19 +1,31 @@
|
|||
# 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 3 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, see <https://www.gnu.org/licenses/>.
|
||||
import gi
|
||||
gi.require_version("Gtk", "3.0")
|
||||
import json
|
||||
from configparser import ConfigParser
|
||||
from .draggable_window import DraggableWindow
|
||||
from .settings import SettingsWindow
|
||||
from .autostart import Autostart
|
||||
from gi.repository import Gtk, Gdk, Pango
|
||||
import logging
|
||||
gi.require_version("Gtk", "3.0")
|
||||
# pylint: disable=wrong-import-position
|
||||
from gi.repository import Gtk
|
||||
|
||||
|
||||
class GeneralSettingsWindow(SettingsWindow):
|
||||
def __init__(self, overlay, overlay2):
|
||||
Gtk.VBox.__init__(self)
|
||||
SettingsWindow.__init__(self)
|
||||
self.overlay = overlay
|
||||
self.overlay2 = overlay
|
||||
self.overlay2 = overlay2
|
||||
self.xshape = None
|
||||
self.autostart = None
|
||||
self.set_size_request(400, 200)
|
||||
self.connect("destroy", self.close_window)
|
||||
self.connect("delete-event", self.close_window)
|
||||
|
|
|
|||
|
|
@ -1,21 +1,32 @@
|
|||
# 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 3 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, see <https://www.gnu.org/licenses/>.
|
||||
import gi
|
||||
gi.require_version("Gtk", "3.0")
|
||||
gi.require_version('GdkPixbuf', '2.0')
|
||||
import urllib
|
||||
import requests
|
||||
import threading
|
||||
from gi.repository.GdkPixbuf import Pixbuf
|
||||
from gi.repository import Gtk, Gio, GdkPixbuf, Gdk
|
||||
import cairo
|
||||
import logging
|
||||
import PIL.Image as Image
|
||||
from io import BytesIO
|
||||
gi.require_version("Gtk", "3.0")
|
||||
gi.require_version('GdkPixbuf', '2.0')
|
||||
# pylint: disable=wrong-import-position
|
||||
from gi.repository import Gio, GdkPixbuf
|
||||
|
||||
|
||||
class Image_Getter():
|
||||
def __init__(self, func, url, id, size):
|
||||
def __init__(self, func, url, identifier, size):
|
||||
self.func = func
|
||||
self.id = id
|
||||
self.id = identifier
|
||||
self.url = url
|
||||
self.size = size
|
||||
|
||||
|
|
@ -28,36 +39,22 @@ class Image_Getter():
|
|||
response = urllib.request.urlopen(req)
|
||||
input_stream = Gio.MemoryInputStream.new_from_data(
|
||||
response.read(), None)
|
||||
pixbuf = Pixbuf.new_from_stream(input_stream, None)
|
||||
pixbuf = GdkPixbuf.Pixbuf.new_from_stream(input_stream, None)
|
||||
if self.size:
|
||||
pixbuf = pixbuf.scale_simple(self.size, self.size,
|
||||
GdkPixbuf.InterpType.BILINEAR)
|
||||
# elif self.limit_x or self.limit_y:
|
||||
# px = pixbuf.width()
|
||||
# py = pixbuf.height()
|
||||
# aspect = px / py
|
||||
# scale = 1.0
|
||||
# if self.limit_x and self.limit_y:
|
||||
# scale = min(self.limit_x / px, self.limit_y / py, 1.0)
|
||||
# elif self.limit_x:
|
||||
# scale = min(self.limit_x / px, 1.0)
|
||||
# elif self.limit_y:
|
||||
# scale = min(self.limit_y / py, 1.0)##
|
||||
#
|
||||
# pixbuf = pixbuf.scale_simple(int(px * scale), int(py * scale),
|
||||
# GdkPixbuf.InterpType.BILINEAR)
|
||||
|
||||
self.func(self.id, pixbuf)
|
||||
except Exception as e:
|
||||
except urllib.error.URLError as exception:
|
||||
logging.error(
|
||||
"Could not access : %s" % (self.url))
|
||||
logging.error(e)
|
||||
"Could not access : %s", self.url)
|
||||
logging.error(exception)
|
||||
|
||||
|
||||
class Surface_Getter():
|
||||
def __init__(self, func, url, id, size):
|
||||
def __init__(self, func, url, identifier, size):
|
||||
self.func = func
|
||||
self.id = id
|
||||
self.id = identifier
|
||||
self.url = url
|
||||
self.size = size
|
||||
|
||||
|
|
@ -71,33 +68,41 @@ class Surface_Getter():
|
|||
surf = self.from_pil(im)
|
||||
|
||||
self.func(self.id, surf)
|
||||
except:
|
||||
logging.error("Unable to open %s" % (self.url))
|
||||
except requests.HTTPError:
|
||||
logging.error("Unable to open %s", self.url)
|
||||
except requests.TooManyRedirects:
|
||||
logging.error("Unable to open %s - Too many redirects", self.url)
|
||||
except requests.Timeout:
|
||||
logging.error("Unable to open %s - Timeout", self.url)
|
||||
except requests.ConnectionError:
|
||||
logging.error("Unable to open %s - Connection error", self.url)
|
||||
except ValueError:
|
||||
logging.error("Unable to read %s", self.url)
|
||||
except TypeError:
|
||||
logging.error("Unable to read %s", self.url)
|
||||
|
||||
def from_pil(self, im, alpha=1.0, format=cairo.FORMAT_ARGB32):
|
||||
def from_pil(self, im, alpha=1.0):
|
||||
"""
|
||||
:param im: Pillow Image
|
||||
:param alpha: 0..1 alpha to add to non-alpha images
|
||||
:param format: Pixel format for output surface
|
||||
"""
|
||||
assert format in (
|
||||
cairo.FORMAT_RGB24, cairo.FORMAT_ARGB32), "Unsupported pixel format: %s" % format
|
||||
if 'A' not in im.getbands():
|
||||
im.putalpha(int(alpha * 256.))
|
||||
arr = bytearray(im.tobytes('raw', 'BGRa'))
|
||||
surface = cairo.ImageSurface.create_for_data(
|
||||
arr, format, im.width, im.height)
|
||||
arr, cairo.FORMAT_ARGB32, im.width, im.height)
|
||||
return surface
|
||||
|
||||
|
||||
def get_image(func, id, ava, size):
|
||||
image_getter = Image_Getter(func, id, ava, size)
|
||||
def get_image(func, identifier, ava, size):
|
||||
image_getter = Image_Getter(func, identifier, ava, size)
|
||||
t = threading.Thread(target=image_getter.get_url, args=())
|
||||
t.start()
|
||||
|
||||
|
||||
def get_surface(func, id, ava, size):
|
||||
image_getter = Surface_Getter(func, id, ava, size)
|
||||
def get_surface(func, identifier, ava, size):
|
||||
image_getter = Surface_Getter(func, identifier, ava, size)
|
||||
t = threading.Thread(target=image_getter.get_url, args=())
|
||||
t.start()
|
||||
|
||||
|
|
@ -106,7 +111,7 @@ def get_aspected_size(img, w, h, anchor=0, hanchor=0):
|
|||
px = img.get_width()
|
||||
py = img.get_height()
|
||||
if py < 1 or h < 1:
|
||||
return (0, 0)
|
||||
return (0, 0, 0, 0)
|
||||
img_aspect = px / py
|
||||
rect_aspect = w / h
|
||||
|
||||
|
|
|
|||
|
|
@ -1,9 +1,22 @@
|
|||
import gi
|
||||
gi.require_version("Gtk", "3.0")
|
||||
from gi.repository import Gtk, Gdk, GtkLayerShell
|
||||
import cairo
|
||||
import logging
|
||||
# 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 3 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, see <https://www.gnu.org/licenses/>.
|
||||
import sys
|
||||
import logging
|
||||
import gi
|
||||
import cairo
|
||||
gi.require_version("Gtk", "3.0")
|
||||
# pylint: disable=wrong-import-position
|
||||
from gi.repository import Gtk, Gdk, GtkLayerShell
|
||||
|
||||
|
||||
class OverlayWindow(Gtk.Window):
|
||||
|
|
@ -23,7 +36,7 @@ class OverlayWindow(Gtk.Window):
|
|||
screen = self.get_screen()
|
||||
self.set_size_request(50, 50)
|
||||
|
||||
self.connect('draw', self.draw)
|
||||
self.connect('draw', self.overlay_draw)
|
||||
|
||||
self.compositing = False
|
||||
# Set RGBA
|
||||
|
|
@ -65,10 +78,7 @@ class OverlayWindow(Gtk.Window):
|
|||
GtkLayerShell.set_anchor(self, GtkLayerShell.Edge.BOTTOM, True)
|
||||
GtkLayerShell.set_anchor(self, GtkLayerShell.Edge.TOP, True)
|
||||
|
||||
def draw(self, widget, context):
|
||||
self.do_draw(context)
|
||||
|
||||
def do_draw(self, context):
|
||||
def overlay_draw(self, _w, context, data=None):
|
||||
pass
|
||||
|
||||
def set_font(self, name, size):
|
||||
|
|
@ -146,7 +156,7 @@ class OverlayWindow(Gtk.Window):
|
|||
(w, h) = self.get_size()
|
||||
surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, w, h)
|
||||
surface_ctx = cairo.Context(surface)
|
||||
self.do_draw(surface_ctx)
|
||||
self.overlay_draw(None, surface_ctx)
|
||||
reg = Gdk.cairo_region_create_from_surface(surface)
|
||||
gdkwin.shape_combine_region(reg, 0, 0)
|
||||
else:
|
||||
|
|
@ -156,7 +166,6 @@ class OverlayWindow(Gtk.Window):
|
|||
def set_monitor(self, idx=None, mon=None):
|
||||
self.monitor = idx
|
||||
if self.is_wayland:
|
||||
print(self)
|
||||
if mon:
|
||||
GtkLayerShell.set_monitor(self, mon)
|
||||
self.force_location()
|
||||
|
|
|
|||
|
|
@ -1,9 +1,21 @@
|
|||
# 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 3 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, see <https://www.gnu.org/licenses/>.
|
||||
import os
|
||||
import logging
|
||||
import gi
|
||||
gi.require_version("Gtk", "3.0")
|
||||
import sys
|
||||
import os
|
||||
# pylint: disable=wrong-import-position
|
||||
from gi.repository import Gtk, Gdk
|
||||
import logging
|
||||
|
||||
|
||||
try:
|
||||
|
|
@ -13,13 +25,24 @@ except ModuleNotFoundError:
|
|||
|
||||
|
||||
class SettingsWindow(Gtk.VBox):
|
||||
def __init__(self):
|
||||
Gtk.VBox.__init__(self)
|
||||
self.placement_window = None
|
||||
self.configDir = None
|
||||
self.configFile = None
|
||||
self.overlay = None
|
||||
self.floating_x = None
|
||||
self.floating_y = None
|
||||
self.floating_w = None
|
||||
self.floating_h = None
|
||||
|
||||
def init_config(self):
|
||||
self.configDir = os.path.join(xdg_config_home, "discover_overlay")
|
||||
os.makedirs(self.configDir, exist_ok=True)
|
||||
self.configFile = os.path.join(self.configDir, "config.ini")
|
||||
self.read_config()
|
||||
|
||||
def close_window(self, a=None, b=None):
|
||||
def close_window(self, _a=None, _b=None):
|
||||
if self.placement_window:
|
||||
(x, y) = self.placement_window.get_position()
|
||||
(w, h) = self.placement_window.get_size()
|
||||
|
|
@ -41,7 +64,7 @@ class SettingsWindow(Gtk.VBox):
|
|||
if display.get_monitor(i).get_model() == name:
|
||||
return i
|
||||
logging.info(
|
||||
"Could not find monitor : %s" % (name))
|
||||
"Could not find monitor : %s", name)
|
||||
return 0
|
||||
|
||||
def get_monitor_obj(self, name):
|
||||
|
|
@ -51,8 +74,14 @@ class SettingsWindow(Gtk.VBox):
|
|||
if display.get_monitor(i).get_model() == name:
|
||||
return display.get_monitor(i)
|
||||
logging.info(
|
||||
"Could not find monitor : %s" % (name))
|
||||
"Could not find monitor : %s", name)
|
||||
return None
|
||||
|
||||
def present(self):
|
||||
def present_settings(self):
|
||||
self.show_all()
|
||||
|
||||
def read_config(self):
|
||||
pass
|
||||
|
||||
def save_config(self):
|
||||
pass
|
||||
|
|
|
|||
|
|
@ -1,13 +1,22 @@
|
|||
# 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 3 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, see <https://www.gnu.org/licenses/>.
|
||||
from .voice_settings import VoiceSettingsWindow
|
||||
from .text_settings import TextSettingsWindow
|
||||
from .general_settings import GeneralSettingsWindow
|
||||
|
||||
import gi
|
||||
gi.require_version("Gtk", "3.0")
|
||||
import sys
|
||||
import os
|
||||
from gi.repository import Gtk, Gdk
|
||||
import logging
|
||||
# pylint: disable=wrong-import-position
|
||||
from gi.repository import Gtk
|
||||
|
||||
|
||||
class MainSettingsWindow(Gtk.Window):
|
||||
|
|
@ -33,7 +42,8 @@ class MainSettingsWindow(Gtk.Window):
|
|||
self.text_settings = TextSettingsWindow(self.text_overlay)
|
||||
nb.append_page(self.text_settings)
|
||||
nb.set_tab_label_text(self.text_settings, "Text")
|
||||
self.core_settings = GeneralSettingsWindow(self.text_overlay,self.voice_overlay)
|
||||
self.core_settings = GeneralSettingsWindow(
|
||||
self.text_overlay, self.voice_overlay)
|
||||
nb.append_page(self.core_settings)
|
||||
nb.set_tab_label_text(self.core_settings, "Core")
|
||||
self.add(nb)
|
||||
|
|
@ -46,9 +56,9 @@ class MainSettingsWindow(Gtk.Window):
|
|||
self.hide()
|
||||
return True
|
||||
|
||||
def present(self):
|
||||
self.voice_settings.present()
|
||||
self.text_settings.present()
|
||||
self.core_settings.present()
|
||||
def present_settings(self):
|
||||
self.voice_settings.present_settings()
|
||||
self.text_settings.present_settings()
|
||||
self.core_settings.present_settings()
|
||||
self.nb.show()
|
||||
self.show()
|
||||
|
|
@ -1,14 +1,27 @@
|
|||
import gi
|
||||
gi.require_version("Gtk", "3.0")
|
||||
gi.require_version('PangoCairo', '1.0')
|
||||
import math
|
||||
# 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 3 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, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
from .overlay import OverlayWindow
|
||||
from gi.repository import Gtk, Gdk, Pango, PangoCairo
|
||||
import cairo
|
||||
import logging
|
||||
import time
|
||||
import re
|
||||
from .image_getter import get_surface, draw_img_to_rect, get_aspected_size
|
||||
import gi
|
||||
gi.require_version("Gtk", "3.0")
|
||||
gi.require_version('PangoCairo', '1.0')
|
||||
# pylint: disable=wrong-import-position
|
||||
from gi.repository import Pango, PangoCairo
|
||||
|
||||
|
||||
class TextOverlayWindow(OverlayWindow):
|
||||
|
|
@ -111,17 +124,14 @@ class TextOverlayWindow(OverlayWindow):
|
|||
elif msg['type'] == 'br':
|
||||
ret = '\n'
|
||||
else:
|
||||
logging.error("Unknown text type : %s" % (msg["type"]))
|
||||
logging.error("Unknown text type : %s", msg["type"])
|
||||
return ret
|
||||
|
||||
def recv_attach(self, id, pix):
|
||||
self.attachment[id] = pix
|
||||
def recv_attach(self, identifier, pix):
|
||||
self.attachment[identifier] = pix
|
||||
self.redraw()
|
||||
|
||||
def draw(self, widget, ctx):
|
||||
self.do_draw(ctx)
|
||||
|
||||
def do_draw(self, context):
|
||||
def overlay_draw(self, _w, context, data=None):
|
||||
self.context = context
|
||||
context.set_antialias(cairo.ANTIALIAS_GOOD)
|
||||
(w, h) = self.get_size()
|
||||
|
|
@ -141,8 +151,6 @@ class TextOverlayWindow(OverlayWindow):
|
|||
context.rectangle(0, 0, w, h)
|
||||
context.clip()
|
||||
|
||||
|
||||
|
||||
cy = h
|
||||
tnow = time.time()
|
||||
for line in reversed(self.content):
|
||||
|
|
@ -181,13 +189,13 @@ class TextOverlayWindow(OverlayWindow):
|
|||
ih = pix.get_height()
|
||||
iw = min(iw, self.w)
|
||||
ih = min(ih, (self.h * .7))
|
||||
(ax, ay, aw, ah) = get_aspected_size(pix, iw, ih)
|
||||
(_ax, _ay, _aw, ah) = get_aspected_size(pix, iw, ih)
|
||||
self.col(self.bg_col)
|
||||
self.context.rectangle(0, y - ah, self.w, ah)
|
||||
|
||||
self.context.fill()
|
||||
self.context.set_operator(cairo.OPERATOR_OVER)
|
||||
new_w, new_h = draw_img_to_rect(
|
||||
_new_w, new_h = draw_img_to_rect(
|
||||
pix, self.context, 0, y - ih, iw, ih, aspect=True)
|
||||
return y - new_h
|
||||
return y
|
||||
|
|
@ -204,7 +212,7 @@ class TextOverlayWindow(OverlayWindow):
|
|||
font = Pango.FontDescription(
|
||||
"%s %s" % (self.text_font, self.text_size))
|
||||
layout.set_font_description(font)
|
||||
tw, th = layout.get_pixel_size()
|
||||
_tw, th = layout.get_pixel_size()
|
||||
self.col(self.bg_col)
|
||||
self.context.rectangle(0, y - th, self.w, th)
|
||||
self.context.fill()
|
||||
|
|
@ -223,7 +231,7 @@ class TextOverlayWindow(OverlayWindow):
|
|||
|
||||
if len(self.imgList) <= count:
|
||||
break # We fucked up. Who types ` anyway
|
||||
url = self.imgList[count]
|
||||
#url = self.imgList[count]
|
||||
|
||||
at = Pango.attr_shape_new_with_data(
|
||||
self.pango_rect, self.pango_rect, count, None)
|
||||
|
|
@ -236,7 +244,7 @@ class TextOverlayWindow(OverlayWindow):
|
|||
PangoCairo.show_layout(self.context, layout)
|
||||
return y - th
|
||||
|
||||
def render_custom(self, ctx, shape, path, data):
|
||||
def render_custom(self, ctx, shape, path, _data):
|
||||
key = self.imgList[shape.data]['url']
|
||||
if key not in self.attachment:
|
||||
get_surface(self.recv_attach,
|
||||
|
|
|
|||
|
|
@ -1,18 +1,33 @@
|
|||
import gi
|
||||
gi.require_version("Gtk", "3.0")
|
||||
# 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 3 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, see <https://www.gnu.org/licenses/>.
|
||||
import json
|
||||
from configparser import ConfigParser
|
||||
from .draggable_window import DraggableWindow
|
||||
from .draggable_window_wayland import DraggableWindowWayland
|
||||
from .settings import SettingsWindow
|
||||
from gi.repository import Gtk, Gdk, Pango
|
||||
import logging
|
||||
import gi
|
||||
gi.require_version("Gtk", "3.0")
|
||||
# pylint: disable=wrong-import-position
|
||||
from gi.repository import Gtk, Gdk, Pango
|
||||
|
||||
|
||||
GUILD_DEFAULT_VALUE = "0"
|
||||
|
||||
|
||||
class TextSettingsWindow(SettingsWindow):
|
||||
def __init__(self, overlay):
|
||||
Gtk.VBox.__init__(self)
|
||||
SettingsWindow.__init__(self)
|
||||
self.overlay = overlay
|
||||
self.set_size_request(400, 200)
|
||||
self.connect("destroy", self.close_window)
|
||||
|
|
@ -27,7 +42,6 @@ class TextSettingsWindow(SettingsWindow):
|
|||
self.ignore_guild_change = False
|
||||
self.create_gui()
|
||||
|
||||
|
||||
def update_channel_model(self):
|
||||
# potentially organize channels by their group/parent_id
|
||||
# https://discord.com/developers/docs/resources/channel#channel-object-channel-structure
|
||||
|
|
@ -65,13 +79,12 @@ class TextSettingsWindow(SettingsWindow):
|
|||
break
|
||||
idx += 1
|
||||
|
||||
|
||||
def add_connector(self, conn):
|
||||
self.connector = conn
|
||||
if self.channel:
|
||||
self.connector.start_listening_text(self.channel)
|
||||
|
||||
def present(self):
|
||||
def present_settings(self):
|
||||
self.show_all()
|
||||
if not self.floating:
|
||||
self.align_x_widget.show()
|
||||
|
|
@ -164,13 +177,14 @@ class TextSettingsWindow(SettingsWindow):
|
|||
"text", "show_attach", fallback=True)
|
||||
|
||||
logging.info(
|
||||
"Loading saved channel %s" % (self.channel))
|
||||
"Loading saved channel %s", self.channel)
|
||||
|
||||
# Pass all of our config over to the overlay
|
||||
self.overlay.set_enabled(self.enabled)
|
||||
self.overlay.set_align_x(self.align_x)
|
||||
self.overlay.set_align_y(self.align_y)
|
||||
self.overlay.set_monitor(self.get_monitor_index(self.monitor),self.get_monitor_obj(self.monitor))
|
||||
self.overlay.set_monitor(self.get_monitor_index(
|
||||
self.monitor), self.get_monitor_obj(self.monitor))
|
||||
self.overlay.set_floating(
|
||||
self.floating, self.floating_x, self.floating_y, self.floating_w, self.floating_h)
|
||||
self.overlay.set_bg(self.bg_col)
|
||||
|
|
@ -306,7 +320,6 @@ class TextSettingsWindow(SettingsWindow):
|
|||
|
||||
channel.connect("changed", self.change_channel)
|
||||
rt = Gtk.CellRendererText()
|
||||
#channel.set_row_separator_func(lambda model, path: model[path][1])
|
||||
channel.pack_start(rt, True)
|
||||
channel.add_attribute(rt, "text", 0)
|
||||
channel.add_attribute(rt, 'sensitive', 1)
|
||||
|
|
@ -315,8 +328,7 @@ class TextSettingsWindow(SettingsWindow):
|
|||
guild = Gtk.ComboBox.new()
|
||||
|
||||
guild.connect("changed", self.change_guild)
|
||||
guild_rt = Gtk.CellRendererText()
|
||||
#guild.set_row_separator_func(lambda model, path: model[path][1])
|
||||
rt = Gtk.CellRendererText()
|
||||
guild.pack_start(rt, True)
|
||||
guild.add_attribute(rt, "text", 0)
|
||||
guild.add_attribute(rt, 'sensitive', 1)
|
||||
|
|
@ -384,7 +396,6 @@ class TextSettingsWindow(SettingsWindow):
|
|||
self.channel = c
|
||||
self.save_config()
|
||||
|
||||
|
||||
def change_guild(self, button):
|
||||
if self.ignore_guild_change:
|
||||
return
|
||||
|
|
|
|||
|
|
@ -1,12 +1,19 @@
|
|||
import gi
|
||||
|
||||
gi.require_version("Gtk", "3.0")
|
||||
# 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 3 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, see <https://www.gnu.org/licenses/>.
|
||||
import math
|
||||
import cairo
|
||||
from .overlay import OverlayWindow
|
||||
from .image_getter import get_surface, draw_img_to_rect
|
||||
from gi.repository import Gtk, Gdk
|
||||
import cairo
|
||||
import logging
|
||||
|
||||
|
||||
class VoiceOverlayWindow(OverlayWindow):
|
||||
|
|
@ -137,11 +144,7 @@ class VoiceOverlayWindow(OverlayWindow):
|
|||
self.connected = is_connected
|
||||
self.redraw()
|
||||
|
||||
def draw(self, widget, context):
|
||||
# Draw
|
||||
self.do_draw(context)
|
||||
|
||||
def do_draw(self, context):
|
||||
def overlay_draw(self, _w, context, _data=None):
|
||||
self.context = context
|
||||
context.set_antialias(cairo.ANTIALIAS_GOOD)
|
||||
# Get size of window
|
||||
|
|
@ -163,7 +166,6 @@ class VoiceOverlayWindow(OverlayWindow):
|
|||
context.rectangle(0, 0, w, h)
|
||||
context.clip()
|
||||
|
||||
|
||||
context.set_operator(cairo.OPERATOR_OVER)
|
||||
if not self.connected:
|
||||
return
|
||||
|
|
@ -219,16 +221,16 @@ class VoiceOverlayWindow(OverlayWindow):
|
|||
context.restore()
|
||||
self.context = None
|
||||
|
||||
def recv_avatar(self, id, pix):
|
||||
if id == 'def':
|
||||
def recv_avatar(self, identifier, pix):
|
||||
if identifier == 'def':
|
||||
self.def_avatar = pix
|
||||
else:
|
||||
self.avatars[id] = pix
|
||||
self.avatars[identifier] = pix
|
||||
self.redraw()
|
||||
|
||||
def delete_avatar(self, id):
|
||||
def delete_avatar(self, identifier):
|
||||
if id in self.avatars:
|
||||
del self.avatars[id]
|
||||
del self.avatars[identifier]
|
||||
|
||||
def draw_avatar(self, context, user, y):
|
||||
# Ensure pixbuf for avatar
|
||||
|
|
@ -282,7 +284,7 @@ class VoiceOverlayWindow(OverlayWindow):
|
|||
context.set_font_face(cairo.ToyFontFace(
|
||||
self.text_font, cairo.FontSlant.NORMAL, cairo.FontWeight.NORMAL))
|
||||
context.set_font_size(self.text_size)
|
||||
xb, yb, w, h, dx, dy = context.text_extents(string)
|
||||
_xb, _yb, w, h, _dx, _dy = context.text_extents(string)
|
||||
ho = (self.avatar_size / 2) - (h / 2)
|
||||
if self.align_right:
|
||||
context.move_to(0, 0)
|
||||
|
|
|
|||
|
|
@ -1,27 +1,41 @@
|
|||
import gi
|
||||
gi.require_version("Gtk", "3.0")
|
||||
# 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 3 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, see <https://www.gnu.org/licenses/>.
|
||||
import json
|
||||
from configparser import ConfigParser
|
||||
import gi
|
||||
from .draggable_window import DraggableWindow
|
||||
from .draggable_window_wayland import DraggableWindowWayland
|
||||
from .settings import SettingsWindow
|
||||
gi.require_version("Gtk", "3.0")
|
||||
# pylint: disable=wrong-import-position
|
||||
from gi.repository import Gtk, Gdk, Pango
|
||||
import logging
|
||||
|
||||
|
||||
class VoiceSettingsWindow(SettingsWindow):
|
||||
def __init__(self, overlay):
|
||||
Gtk.VBox.__init__(self)
|
||||
SettingsWindow.__init__(self)
|
||||
self.overlay = overlay
|
||||
self.set_size_request(400, 200)
|
||||
self.connect("destroy", self.close_window)
|
||||
self.connect("delete-event", self.close_window)
|
||||
self.placement_window = None
|
||||
self.align_x = None
|
||||
self.align_y = None
|
||||
self.init_config()
|
||||
|
||||
self.create_gui()
|
||||
|
||||
def present(self):
|
||||
def present_settings(self):
|
||||
self.show_all()
|
||||
if not self.floating:
|
||||
self.align_x_widget.show()
|
||||
|
|
@ -85,7 +99,8 @@ class VoiceSettingsWindow(SettingsWindow):
|
|||
self.overlay.set_only_speaking(self.only_speaking)
|
||||
self.overlay.set_highlight_self(self.highlight_self)
|
||||
self.overlay.set_icon_only(self.icon_only)
|
||||
self.overlay.set_monitor(self.get_monitor_index(self.monitor),self.get_monitor_obj(self.monitor))
|
||||
self.overlay.set_monitor(self.get_monitor_index(
|
||||
self.monitor), self.get_monitor_obj(self.monitor))
|
||||
self.overlay.set_vert_edge_padding(self.vert_edge_padding)
|
||||
self.overlay.set_horz_edge_padding(self.horz_edge_padding)
|
||||
self.overlay.set_order(self.order)
|
||||
|
|
@ -337,8 +352,6 @@ class VoiceSettingsWindow(SettingsWindow):
|
|||
|
||||
self.add(box)
|
||||
|
||||
pass
|
||||
|
||||
def change_placement(self, button):
|
||||
if self.placement_window:
|
||||
(x, y, w, h) = self.placement_window.get_coords()
|
||||
|
|
@ -347,7 +360,7 @@ class VoiceSettingsWindow(SettingsWindow):
|
|||
self.floating_w = w
|
||||
self.floating_h = h
|
||||
self.overlay.set_floating(True, x, y, w, h)
|
||||
self.save_config
|
||||
self.save_config()
|
||||
if not self.overlay.is_wayland:
|
||||
button.set_label("Place Window")
|
||||
self.placement_window.close()
|
||||
|
|
@ -448,7 +461,6 @@ class VoiceSettingsWindow(SettingsWindow):
|
|||
m_s = mon.get_model()
|
||||
self.overlay.set_monitor(button.get_active(), mon)
|
||||
|
||||
|
||||
self.monitor = m_s
|
||||
self.save_config()
|
||||
|
||||
|
|
|
|||
2
setup.py
2
setup.py
|
|
@ -9,7 +9,7 @@ setup(
|
|||
name='discover-overlay',
|
||||
author='trigg',
|
||||
author_email='',
|
||||
version='0.2.2',
|
||||
version='0.3.0',
|
||||
description='Voice chat overlay',
|
||||
long_description=readme(),
|
||||
long_description_content_type='text/markdown',
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue