enhances window border feature thing and adds a widget for it
M winrustler/__main__.py +1 -1
@@ 27,7 27,7 @@ from winrustler.core import REGISTRY
 from winrustler.winapi import WindowDiscovery, search
 
 # Imported for their side effects ...
-from winrustler import deborder, mover, fader
+from winrustler import border, mover, fader
 
 
 def main():

          
A => winrustler/border.py +40 -0
@@ 0,0 1,40 @@ 
+import argparse
+import ctypes
+from ctypes import wintypes
+
+import attr
+
+from winrustler.core import register_module
+from winrustler.winconsts import *
+
+user32 = ctypes.windll.user32
+
+def from_args(collection, args):
+    hwnd = collection.search(args.window)
+    return BorderWindow(hwnd)
+
+
+@register_module()
+@attr.s(frozen=True)
+class BorderWindow(object):
+    hwnd = attr.ib()
+    have = attr.ib(default=False)
+
+    @classmethod
+    def add_subparser(cls, subparsers):
+        parser = subparsers.add_parser('border')
+        parser.add_argument('--remove', action='store_false', dest='have')
+        return parser
+
+    def run(self):
+        style = user32.GetWindowLongA(self.hwnd, GWL_STYLE)
+        if self.have:
+            style |= (WS_SIZEBOX | WS_CAPTION)
+        else:
+            style &= ~(WS_SIZEBOX | WS_CAPTION)
+        if 0 == user32.SetWindowLongA(self.hwnd, GWL_STYLE, style):
+            raise ctypes.WinError()
+
+    def summarized(self):
+        what = "Add" if self.have else "Remove"
+        return "{} window border".format(what)

          
R winrustler/deborder.py =>  +0 -31
@@ 1,31 0,0 @@ 
-import argparse
-import ctypes
-from ctypes import wintypes
-
-import attr
-
-from winrustler.core import register_module
-from winrustler.winconsts import *
-
-user32 = ctypes.windll.user32
-
-def from_args(collection, args):
-    hwnd = collection.search(args.window)
-    return DeborderWindow(hwnd)
-
-
-@register_module()
-@attr.s(frozen=True)
-class DeborderWindow(object):
-    hwnd = attr.ib()
-
-    @classmethod
-    def add_subparser(cls, subparsers):
-        parser = subparsers.add_parser('deborder')
-        return parser
-
-    def run(self):
-        style = user32.GetWindowLongA(self.hwnd, GWL_STYLE)
-        style &= ~(WS_SIZEBOX | WS_CAPTION)
-        if 0 == user32.SetWindowLongA(self.hwnd, GWL_STYLE, style):
-            raise ctypes.WinError()

          
M winrustler/ui/history.py +2 -0
@@ 43,9 43,11 @@ class PastRustle(object):
 
 from winrustler.fader import FadeWindow
 from winrustler.mover import MoveWindow
+from winrustler.border import BorderWindow
 serialization = Serialization()
 serialization.know(FadeWindow, 'fade')
 serialization.know(MoveWindow, 'move')
+serialization.know(BorderWindow, 'border')
 serialization.know(PastRustle, 'past')
 
 

          
A => winrustler/ui/res/1f5bc.png +0 -0

        
M winrustler/ui/rustle.py +4 -0
@@ 1,5 1,6 @@ 
 from winrustler.mover import MoveWindow
 from winrustler.fader import FadeWindow
+from winrustler.border import BorderWindow
 from winrustler.winapi import get_window_title
 
 

          
@@ 9,5 10,8 @@ def rustle_description(rustle):
         return "Moved {title} to {rustle.x} x {rustle.y}.".format(**locals())
     elif isinstance(rustle, FadeWindow):
         return "Set {title} opacity to {rustle.opacity}.".format(**locals())
+    elif isinstance(rustle, BorderWindow):
+        what = "Added" if rustle.have else "Removed"
+        return "{what} window border for {title}.".format(**locals())
     else:
         return "Did something, not sure what."

          
M winrustler/ui/widgets/rustle.py +20 -0
@@ 13,6 13,7 @@ from PyQt5.QtWidgets import (
 
 from winrustler.mover import MoveWindow
 from winrustler.fader import FadeWindow
+from winrustler.border import BorderWindow
 
 
 class MoveControls(QWidget):

          
@@ 72,3 73,22 @@ class FadeControls(QWidget):
 
     def window_request(self, hwnd):
         return FadeWindow(hwnd, self._opacity.value())
+
+
+class BorderControls(QWidget):
+
+    updated = pyqtSignal()
+
+    def __init__(self, *args, **kwargs):
+        super().__init__(*args, **kwargs)
+
+        self._description = QLabel("<p>Add or remove a window border.</p>", parent=self)
+        self._have = QCheckBox("Add a border, leave unchecked to eliminate it", self)
+
+        self._layout = QFormLayout(self)
+        self._layout.addRow(self._description)
+        self._layout.addRow(self._have)
+        self.setLayout(self._layout)
+
+    def window_request(self, hwnd):
+        return BorderWindow(hwnd, have=self._have.checkState()==Qt.Checked)

          
M winrustler/ui/widgets/rustlerwindow.py +3 -1
@@ 12,7 12,7 @@ from PyQt5.QtWidgets import (
 from winrustler.ui import icon
 from winrustler.ui.debug import show_exceptions
 from winrustler.ui.widgets.select import WindowSelect
-from winrustler.ui.widgets.rustle import MoveControls, FadeControls
+from winrustler.ui.widgets.rustle import MoveControls, FadeControls, BorderControls
 from winrustler.ui.widgets.match import MatchDialog
 from winrustler.ui.state import save_window_geometry, restore_window_geometry
 

          
@@ 32,10 32,12 @@ class RustlerWindow(QDialog):
 
         self._move = MoveControls(self)
         self._fade = FadeControls(self)
+        self._border = BorderControls(self)
 
         self._function_tab = QTabWidget(self)
         self._function_tab.addTab(self._move, icon('1f4d0.png'), "M&ove")
         self._function_tab.addTab(self._fade, icon('1f47b.png'), "&Fade")
+        self._function_tab.addTab(self._border, icon('1f5bc.png'), "&Border")
 
         self._bb = QDialogButtonBox(self)
         self._bb.accepted.connect(self.accept)