Blob Blame History Raw
From e4e7210b3bd669bfeb8015f66163e7e49d710d1d Mon Sep 17 00:00:00 2001
From: Jonathon Jongsma <jjongsma@redhat.com>
Date: Wed, 18 May 2022 17:03:30 -0500
Subject: [PATCH] virt-manager: add support for qemu-vdagent channel

 This provides the UI support for the qemu-vdagent channel which allows
 clipboard sharing with VNC graphics (see previous commit for more
 information).

 The channel name in the device list was changed slightly in order to
 avoid confusion. Due to the fact that both the spice-vdagent and the
 qemu-vdagent specify the same virtio name (com.redhat.spice.0), both of
 these channels were showing up in the device list as "Channel spice",
 which is a bit confusing.

 In order to disambiguate these, channels now show up in the device list
 as "Channel {type} ({name})" instead of "Channel {name}". So for
 example, a qemu-vdagent channel would show up as:
    Channel Qemu vdagent (spice)
Whereas a spice-vdagent channel would show up as:
    Channel Spice agent (spice)

Signed-off-by: Jonathon Jongsma <jjongsma@redhat.com>
(cherry picked from commit caa99a6001be0c86a1dd0eb5fc0ce142ab929a31)

Resolves https://bugzilla.redhat.com/show_bug.cgi?id=2060724

Signed-off-by: Jonathon Jongsma <jjongsma@redhat.com>
---
 ui/addhardware.ui              | 28 +++++++++++++++++++++++++++-
 ui/details.ui                  | 27 ++++++++++++++++++++++++++-
 virtManager/addhardware.py     | 10 +++++++++-
 virtManager/details/details.py |  7 +++++--
 4 files changed, 67 insertions(+), 5 deletions(-)

diff --git a/ui/addhardware.ui b/ui/addhardware.ui
index fa88127b8..f212481a3 100644
--- a/ui/addhardware.ui
+++ b/ui/addhardware.ui
@@ -725,7 +725,7 @@
                               </packing>
                             </child>
                             <child>
-                              <!-- n-columns=2 n-rows=6 -->
+                              <!-- n-columns=2 n-rows=7 -->
                               <object class="GtkGrid" id="char-table">
                                 <property name="visible">True</property>
                                 <property name="can-focus">False</property>
@@ -901,6 +901,32 @@
                                     <property name="top-attach">2</property>
                                   </packing>
                                 </child>
+                                <child>
+                                  <object class="GtkLabel" id="char-vdagent-clipboard-label">
+                                    <property name="visible">True</property>
+                                    <property name="can-focus">False</property>
+                                    <property name="label" translatable="yes">_Share Clipboard:</property>
+                                    <property name="use-underline">True</property>
+                                    <property name="mnemonic-widget">char-vdagent-clipboard</property>
+                                  </object>
+                                  <packing>
+                                    <property name="left-attach">0</property>
+                                    <property name="top-attach">6</property>
+                                  </packing>
+                                </child>
+                                <child>
+                                  <object class="GtkCheckButton" id="char-vdagent-clipboard">
+                                    <property name="visible">True</property>
+                                    <property name="can-focus">True</property>
+                                    <property name="receives-default">False</property>
+                                    <property name="halign">start</property>
+                                    <property name="draw-indicator">True</property>
+                                  </object>
+                                  <packing>
+                                    <property name="left-attach">1</property>
+                                    <property name="top-attach">6</property>
+                                  </packing>
+                                </child>
                                 <child internal-child="accessible">
                                   <object class="AtkObject" id="char-table-atkobject">
                                     <property name="AtkObject::accessible-name">char-tab</property>
diff --git a/ui/details.ui b/ui/details.ui
index 10b308242..264f7cdd4 100644
--- a/ui/details.ui
+++ b/ui/details.ui
@@ -3506,7 +3506,7 @@
                             <property name="margin-start">12</property>
                             <property name="margin-top">3</property>
                             <child>
-                              <!-- n-columns=2 n-rows=7 -->
+                              <!-- n-columns=2 n-rows=8 -->
                               <object class="GtkGrid" id="table37">
                                 <property name="visible">True</property>
                                 <property name="can-focus">False</property>
@@ -3601,6 +3601,19 @@
                                     <property name="top-attach">6</property>
                                   </packing>
                                 </child>
+                                <child>
+                                  <object class="GtkLabel" id="char-clipboard-sharing">
+                                    <property name="visible">True</property>
+                                    <property name="can-focus">False</property>
+                                    <property name="halign">start</property>
+                                    <property name="label" translatable="yes">label507</property>
+                                    <property name="selectable">True</property>
+                                  </object>
+                                  <packing>
+                                    <property name="left-attach">1</property>
+                                    <property name="top-attach">7</property>
+                                  </packing>
+                                </child>
                                 <child>
                                   <object class="GtkLabel" id="char-source-host">
                                     <property name="visible">True</property>
@@ -3673,6 +3686,18 @@
                                     <property name="top-attach">6</property>
                                   </packing>
                                 </child>
+                                <child>
+                                  <object class="GtkLabel" id="char-clipboard-sharing-label">
+                                    <property name="visible">True</property>
+                                    <property name="can-focus">False</property>
+                                    <property name="halign">end</property>
+                                    <property name="label" translatable="yes">Clipboard:</property>
+                                  </object>
+                                  <packing>
+                                    <property name="left-attach">0</property>
+                                    <property name="top-attach">7</property>
+                                  </packing>
+                                </child>
                                 <child>
                                   <object class="GtkLabel" id="char-source-path-label">
                                     <property name="visible">True</property>
diff --git a/virtManager/addhardware.py b/virtManager/addhardware.py
index 8c7fa0c72..0a8e33d30 100644
--- a/virtManager/addhardware.py
+++ b/virtManager/addhardware.py
@@ -308,6 +308,7 @@ class vmmAddHardware(vmmGObjectUI):
         self.widget("char-path").set_text("")
         self.widget("char-channel").set_text("")
         self.widget("char-auto-socket").set_active(True)
+        self.widget("char-vdagent-clipboard").set_active(True)
 
 
         # RNG params
@@ -399,7 +400,8 @@ class vmmAddHardware(vmmGObjectUI):
                DeviceSerial.TYPE_UNIX]
         if char_class.XML_NAME == "channel":
             ret = [DeviceSerial.TYPE_SPICEVMC,
-                   DeviceSerial.TYPE_SPICEPORT] + ret
+                   DeviceSerial.TYPE_SPICEPORT,
+                   DeviceSerial.TYPE_QEMUVDAGENT] + ret
         return ret
 
     @staticmethod
@@ -425,6 +427,7 @@ class vmmAddHardware(vmmGObjectUI):
             DeviceSerial.TYPE_UNIX: _("UNIX socket"),
             DeviceSerial.TYPE_SPICEVMC: _("Spice agent"),
             DeviceSerial.TYPE_SPICEPORT: _("Spice port"),
+            DeviceSerial.TYPE_QEMUVDAGENT: _("QEMU vdagent"),
         }
         return labels.get(val, val)
 
@@ -1114,11 +1117,14 @@ class vmmAddHardware(vmmGObjectUI):
         supports_path = [dev.TYPE_FILE, dev.TYPE_UNIX,
                          dev.TYPE_DEV, dev.TYPE_PIPE]
         supports_channel = [dev.TYPE_SPICEPORT]
+        supports_clipboard = [dev.TYPE_QEMUVDAGENT]
 
         uiutil.set_grid_row_visible(self.widget("char-path-label"),
                 devtype in supports_path)
         uiutil.set_grid_row_visible(self.widget("char-channel-label"),
                 devtype in supports_channel)
+        uiutil.set_grid_row_visible(self.widget("char-vdagent-clipboard-label"),
+                devtype in supports_clipboard)
 
         uiutil.set_grid_row_visible(
             self.widget("char-target-name-label"), ischan)
@@ -1472,6 +1478,7 @@ class vmmAddHardware(vmmGObjectUI):
         source_channel = self.widget("char-channel").get_text()
         target_name = self.widget("char-target-name").get_child().get_text()
         target_type = uiutil.get_list_selection(typebox)
+        clipboard = self.widget("char-vdagent-clipboard").get_active()
 
         if not self.widget("char-path").get_visible():
             source_path = None
@@ -1486,6 +1493,7 @@ class vmmAddHardware(vmmGObjectUI):
         dev.type = devtype
         dev.source.path = source_path
         dev.source.channel = source_channel
+        dev.source.clipboard_copypaste = clipboard
         dev.target_name = target_name
         dev.target_type = target_type
         return dev
diff --git a/virtManager/details/details.py b/virtManager/details/details.py
index 24810f0ff..ddc43b767 100644
--- a/virtManager/details/details.py
+++ b/virtManager/details/details.py
@@ -207,10 +207,10 @@ def _label_for_device(dev, disk_bus_index):
         return _("Console %(num)d") % {"num": port + 1}
 
     if devtype == "channel":
+        pretty_type = vmmAddHardware.char_pretty_type(dev.type)
         name = vmmAddHardware.char_pretty_channel_name(dev.target_name)
         if name:
-            return _("Channel %(name)s") % {"name": name}
-        pretty_type = vmmAddHardware.char_pretty_type(dev.type)
+            return _("Channel %(type)s (%(name)s)") % {"type": pretty_type, "name": name}
         return _("Channel %(type)s") % {"type": pretty_type}
 
     if devtype == "graphics":
@@ -2098,6 +2098,7 @@ class vmmDetails(vmmGObjectUI):
         primary = self.vm.serial_is_console_dup(chardev)
         show_target_type = not (char_type in ["serial", "parallel"])
         is_qemuga = chardev.target_name == chardev.CHANNEL_NAME_QEMUGA
+        show_clipboard = chardev.type == chardev.TYPE_QEMUVDAGENT
 
         if char_type == "serial":
             typelabel = _("Serial Device")
@@ -2152,6 +2153,8 @@ class vmmDetails(vmmGObjectUI):
         # notifiations about connection state. For spice this UI field
         # can get out of date
         show_ui("char-target-state", chardev.target_state, doshow=is_qemuga)
+        clipboard = _("On") if chardev.source.clipboard_copypaste else _("Off")
+        show_ui("char-clipboard-sharing", clipboard, doshow=show_clipboard)
 
     def _refresh_hostdev_page(self, hostdev):
         rom_bar = hostdev.rom_bar
-- 
2.35.3