# HG changeset patch # User Goffi # Date 1705398098 -3600 # Node ID 97ab236e8f20d5151646788e00774a68411a1c5a # Parent f0ce49b360c8277d4b5346b62d6da8b1d337ebc5 plugin calls: implement desktop sharing: rel 433 diff -r f0ce49b360c8 -r 97ab236e8f20 libervia/desktop_kivy/plugins/plugin_wid_calls.kv --- a/libervia/desktop_kivy/plugins/plugin_wid_calls.kv Wed Nov 01 13:41:07 2023 +0100 +++ b/libervia/desktop_kivy/plugins/plugin_wid_calls.kv Tue Jan 16 10:41:38 2024 +0100 @@ -14,6 +14,36 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . + +: + size_hint_y: None + height: '44dp' + color: 0.8, 0.8, 0.8, 1 + + +: + title: "Select a Screen or Window" + size_hint: 0.8, 0.8 + windows_buttons: windows_buttons + BoxLayout: + orientation: "vertical" + ScrollView: + BoxLayout: + id: windows_buttons + orientation: "vertical" + size_hint_y: None + height: self.minimum_height + WindowSelectButton: + text: "Full Screen" + on_press: root.on_window_selected(None, None) + + Button: + size_hint_y: None + height: '44dp' + text: 'Close' + on_release: root.dismiss() + + : size_hint: None, None size: "50dp", "50dp" @@ -98,9 +128,9 @@ BoxLayout: id: call_controls orientation: "horizontal" - size_hint: 0.5, None # Adjusted to 50% of the width + size_hint: 0.5, None height: "50dp" - pos_hint: {"x": 0.25, "y": 0.05} # Adjusted starting position + pos_hint: {"x": 0.25, "y": 0.05} spacing: "30dp" Widget: @@ -114,6 +144,18 @@ active: not root.audio_muted on_press: root.audio_muted = not root.audio_muted + CallControlButton: + symbol: "desktop" + active: root.desktop_sharing + background_color: (0.28, 0.78, 0.56, 1) if not self.active else (0.95, 0.27, 0.41, 1) + on_press: root.on_desktop_btn_press() + canvas.after: + Color: + rgba: (0, 0, 0, 0) if self.active else (0.4, 0.4, 0.4, 1) + Line: + points: [self.x + dp(10), self.y + dp(10), self.right - dp(10), self.top - dp(10)] + width: 2 + cap: "round" CallControlButton: symbol: "phone" diff -r f0ce49b360c8 -r 97ab236e8f20 libervia/desktop_kivy/plugins/plugin_wid_calls.py --- a/libervia/desktop_kivy/plugins/plugin_wid_calls.py Wed Nov 01 13:41:07 2023 +0100 +++ b/libervia/desktop_kivy/plugins/plugin_wid_calls.py Tue Jan 16 10:41:38 2024 +0100 @@ -5,6 +5,7 @@ # from gi.repository import GLib from gi.repository import GObject, Gst, GstWebRTC, GstSdp +from kivy.metrics import dp try: from gi.overrides import Gst as _ @@ -27,6 +28,7 @@ from kivy.support import install_gobject_iteration from kivy.uix.button import Button from kivy.uix.image import Image +from kivy.uix.popup import Popup from kivy.uix.screenmanager import Screen from kivy.uix.widget import Widget from libervia.backend.core.constants import Const as C @@ -35,7 +37,7 @@ from libervia.backend.core import exceptions from libervia.backend.tools.common import data_format from libervia.frontends.quick_frontend import quick_widgets -from libervia.frontends.tools import aio, jid, webrtc +from libervia.frontends.tools import aio, display_servers, jid, webrtc from libervia.desktop_kivy import G @@ -101,7 +103,9 @@ test_mode: bool = False - PROXIED_PROPERTIES = {'audio_muted', 'callee', 'sid', 'video_muted'} + PROXIED_PROPERTIES = { + 'audio_muted', 'callee', 'desktop_sharing', 'sid', 'video_muted', 'desktop_sharing_data' + } PROXIED_METHODS = {'answer_call', 'end_call', 'on_accepted_call', 'on_ice_candidates_new', 'setup_call', 'start_pipeline'} def __init__(self, parent_calls: "Calls", profile: str) -> None: @@ -239,11 +243,39 @@ if buf is not None and mapinfo is not None: buf.unmap(mapinfo) +class WindowSelectButton(Button): + pass + + +class DesktopScreenDialog(Popup): + windows_buttons = ObjectProperty() + + def __init__(self, calls: "Calls", **kwargs): + super().__init__(**kwargs) + self.calls = calls + if display_servers.detect() == display_servers.X11: + windows_data = display_servers.x11_list_windows() + for window_data in windows_data: + log.debug(f"- X11 windows found: {window_data}") + button = WindowSelectButton( + text = window_data["title"], + on_press=partial(self.on_window_selected, xid=window_data["id"]) + ) + self.windows_buttons.add_widget(button) + + def on_window_selected(self, instance, xid: str) -> None: + if xid is not None: + self.calls.webrtc.desktop_sharing_data = {"xid": xid} + else: + self.calls.webrtc.desktop_sharing_data = None + self.calls.desktop_sharing = True + self.dismiss() + class Calls( - quick_widgets.QuickWidget, - cagou_widget.LiberviaDesktopKivyWidget, - FilterBehavior + quick_widgets.QuickWidget, + cagou_widget.LiberviaDesktopKivyWidget, + FilterBehavior ): audio_muted = BooleanProperty(False) call_layout = ObjectProperty() @@ -259,6 +291,7 @@ signals_registered = False use_header_input = True video_muted = BooleanProperty(False) + desktop_sharing = BooleanProperty(False) def __init__(self, host, target, profiles): quick_widgets.QuickWidget.__init__(self, G.host, target, profiles) @@ -382,6 +415,15 @@ def on_video_muted(self, instance, muted: bool) -> None: self.webrtc.video_muted = muted + def on_desktop_btn_press(self) -> None: + if self.desktop_sharing: + self.desktop_sharing = False + else: + DesktopScreenDialog(self).open() + + def on_desktop_sharing(self, instance, active: bool) -> None: + self.webrtc.desktop_sharing = active + def on_fullscreen(self, instance, fullscreen: bool) -> None: if fullscreen: G.host.app.show_head_widget(False, animation=False)