changeset 510:97ab236e8f20

plugin calls: implement desktop sharing: rel 433
author Goffi <goffi@goffi.org>
date Tue, 16 Jan 2024 10:41:38 +0100
parents f0ce49b360c8
children 290b405940b5
files libervia/desktop_kivy/plugins/plugin_wid_calls.kv libervia/desktop_kivy/plugins/plugin_wid_calls.py
diffstat 2 files changed, 91 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- 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 <http://www.gnu.org/licenses/>.
 
+
+<WindowSelectButton>:
+    size_hint_y: None
+    height: '44dp'
+    color: 0.8, 0.8, 0.8, 1
+
+
+<DesktopScreenDialog>:
+    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()
+
+
 <CallControlButton>:
     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"
--- 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)