diff --git a/woman/help.py b/woman/help.py
index 4b7e18f0172cc51e23aa46af23fec9489dbcfe51..91ce06f4d9117ffdc9f66f61adb481bad57097d0 100644
--- a/woman/help.py
+++ b/woman/help.py
@@ -54,6 +54,7 @@ On middle-click on a container, floating will be toggled.
 
 You can use drag-and-drop for windows/containers or whole workspaces.
 Using left button only members of container will be taken.
+Using middle button containers will be swapped.
 
 You can search for a window by its name by typing the query to the relevant
 input field (labeled find).
@@ -98,6 +99,7 @@ m<id><id><key>   - Move window/container/workspace near other container
                m       - expand in front of
                j/b/y/d - expand to new horizontal/vertical/tabbed/stacked layout
                J/B/Y/D - expand to new layout before the target container
+               c       - change (swap) workspaces
                     (the second part is the same moved one key right)
 c<id>...          - select container/window/workspace and ...
     m<workspace>  - move to workspace
diff --git a/woman/qt.py b/woman/qt.py
index 1bca128315e97a5003f53ec513939121ad56f28f..1e8695beca4fc4a6b61b334a1f0818512c54750b 100755
--- a/woman/qt.py
+++ b/woman/qt.py
@@ -171,45 +171,49 @@ def qt_main():
             shared.i3_cmd(f'[con_id={target.container_id}] mark tmp')
             shared.i3_cmd(f'[con_id={self.container_id}] move container to mark tmp')
 
-        def move(self, target, before=False, expand=False, new_container=None):
+        def move(self, target, swap=False, before=False, expand=False, new_container=None):
             self.workspace_widget.screenshot_changed()
             target.workspace_widget.screenshot_changed()
-            if new_container is not None:
-                target.put_in_new_container(None if new_container is True else new_container)
-            if expand and type(self) != I3InnerNodeWidget:
-                if before:
-                    self.move(target, expand=True)
-                    target.move(self.nodes[0])
-                else:
-                    marks = []
-                    for (i, it) in enumerate(self.nodes):
-                        shared.i3_cmd(f'[con_id={it.container_id}] mark tmp_from_{i}')
-                        marks.append(f"tmp_from_{i}")
-                    if type(target) == I3WindowNodeWidget:
-                        tmp_win = TmpWin()
-                        shared.i3_cmd(f'[con_id={target.container_id}] swap container with id {tmp_win.id}')
-                        shared.i3_cmd(f'[id={tmp_win.id}] mark tmp')
-                    else:
-                        shared.i3_cmd(f'[con_id={target.container_id}] mark tmp')
-                    shared.i3_cmd(f'[con_mark="{"|".join(marks)}"] move container to mark tmp')
-                    if type(target) == I3WindowNodeWidget:
-                        shared.i3_cmd(f'[con_id={target.container_id}] swap container with id {tmp_win.id}')
+            if swap:
+                shared.i3_cmd(f'[con_id={self.container_id}] mark tmp')
+                shared.i3_cmd(f'[con_id={target.container_id}] swap container with mark tmp')
             else:
-                if before:
-                    self.move(target)
-                    target.move(self)
+                if new_container is not None:
+                    target.put_in_new_container(None if new_container is True else new_container)
+                if expand and type(self) != I3InnerNodeWidget:
+                    if before:
+                        self.move(target, expand=True)
+                        target.move(self.nodes[0])
+                    else:
+                        marks = []
+                        for (i, it) in enumerate(self.nodes):
+                            shared.i3_cmd(f'[con_id={it.container_id}] mark tmp_from_{i}')
+                            marks.append(f"tmp_from_{i}")
+                        if type(target) == I3WindowNodeWidget:
+                            tmp_win = TmpWin()
+                            shared.i3_cmd(f'[con_id={target.container_id}] swap container with id {tmp_win.id}')
+                            shared.i3_cmd(f'[id={tmp_win.id}] mark tmp')
+                        else:
+                            shared.i3_cmd(f'[con_id={target.container_id}] mark tmp')
+                        shared.i3_cmd(f'[con_mark="{"|".join(marks)}"] move container to mark tmp')
+                        if type(target) == I3WindowNodeWidget:
+                            shared.i3_cmd(f'[con_id={target.container_id}] swap container with id {tmp_win.id}')
                 else:
-                    if type(target) == I3WindowNodeWidget:
-                        self.move_to(target)
+                    if before:
+                        self.move(target)
+                        target.move(self)
                     else:
-                        tmp_win = TmpWin()
-                        shared.i3_cmd(f'[con_id={target.container_id}] swap container with id {tmp_win.id}')
-                        shared.i3_cmd(f'[id={tmp_win.id}] mark tmp')
-                        shared.i3_cmd(f'[con_id={self.container_id}] move container to mark tmp')
-                        try:
+                        if type(target) == I3WindowNodeWidget:
+                            self.move_to(target)
+                        else:
+                            tmp_win = TmpWin()
                             shared.i3_cmd(f'[con_id={target.container_id}] swap container with id {tmp_win.id}')
-                        except I3CmdException:
-                            pass  # Could fail whem moving the only window from container to upper container
+                            shared.i3_cmd(f'[id={tmp_win.id}] mark tmp')
+                            shared.i3_cmd(f'[con_id={self.container_id}] move container to mark tmp')
+                            try:
+                                shared.i3_cmd(f'[con_id={target.container_id}] swap container with id {tmp_win.id}')
+                            except I3CmdException:
+                                pass  # Could fail whem moving the only window from container to upper container
 
 
         def do_float(self, state=None):
@@ -276,12 +280,15 @@ def qt_main():
                 m_win.cmd_msg_clean()
                 button = s.press_event_buttons
                 try:
-                    s.move(self,
-                            expand=s.press_event_buttons == Qt.RightButton,
-                            **[{"before":True}, {"new_container": True}, {}][self.drop_place]
-                    )
-                    # [s.expand_before, lambda self: s.move_to_new_container_with(self, expand=True), s.expand_after][self.drop_place](self)
-                    #[s.move_before, s.move_to_new_container_with, s.move_after][self.drop_place](self)
+                    if button == Qt.MiddleButton:
+                        s.move(self, swap=True)
+                    else:
+                        s.move(self,
+                                expand=s.press_event_buttons == Qt.RightButton,
+                                **[{"before":True}, {"new_container": True}, {}][self.drop_place]
+                        )
+                        # [s.expand_before, lambda self: s.move_to_new_container_with(self, expand=True), s.expand_after][self.drop_place](self)
+                        #[s.move_before, s.move_to_new_container_with, s.move_after][self.drop_place](self)
                     m_win.load_i3_tree()
                     self.setStyleSheet(f"")
                     self.redraw()
@@ -311,7 +318,11 @@ def qt_main():
                 self.drop_place = 1
             s = event.source()
             if s is not None and isinstance(s, WorkspaceWidget) or isinstance(s, I3NodeWidget):
-                style = ["border-top: 3px solid green;", "background-color: green;", "border:no; border-bottom: 3px solid green;"][self.drop_place]
+                button = s.press_event_buttons
+                if button == Qt.MiddleButton:
+                    style = "background-color: green;"
+                else:
+                    style = ["border-top: 3px solid green;", "background-color: green;", "border:no; border-bottom: 3px solid green;"][self.drop_place]
                 self.setStyleSheet(f"#{id(self)} {{ {style} }}");
 
     class I3WindowNodeWidget(I3NodeWidget):
@@ -632,11 +643,11 @@ def qt_main():
         def move_to_otput(self, output="next"):
             shared.i3_cmd(f"move workspace to output {output}")
 
-        def move(self, target, before=False, expand=False, new_container=None):
+        def move(self, target, swap=False, before=False, expand=False, new_container=None):
             for f in self._tree.floating_nodes:
                 f.move_to_workspace(target.workspace_widget.master, target.workspace_widget.slave)
             if (w := self.root_i3_tree_widget()) is not None:
-                w.move(target, before=before, expand=expand, new_container=new_container)
+                w.move(target, swap=swap, before=before, expand=expand, new_container=new_container)
 
         def move_to_workspace(self, master, slave, expand=False):
             for f in self._tree.floating_nodes:
@@ -1094,6 +1105,8 @@ def qt_main():
                             nd_from.move(nd_to, new_container="tabbed", before=mod==SHIFT, expand=True)
                         elif mod in [0, SHIFT] and key == ord('D'):
                             nd_from.move(nd_to, new_container="stacked", before=mod==SHIFT, expand=True)
+                        elif mod in [0] and key == ord('C'):
+                            nd_from.move(nd_to, swap=True)
                         else:
                             raise NoSutchKey(key, mod)
                     self.load_i3_tree()