prompt: You will be provided with a partial code base and an issue statement explaining a problem to resolve.
  <issue>
  stack trace from Clipboard widget
  ```
  2021-08-13 06:48:23,421 ERROR libqtile hook.py:fire():L381 Error in hook selection_change
  Traceback (most recent call last):
    File "/home/tycho/.local/lib/python3.9/site-packages/libqtile/hook.py", line 379, in fire
      i(*args, **kwargs)
    File "/home/tycho/.local/lib/python3.9/site-packages/libqtile/widget/clipboard.py", line 82, in hook_change
      if self.is_blacklisted(selection["owner"]):
    File "/home/tycho/.local/lib/python3.9/site-packages/libqtile/widget/clipboard.py", line 69, in is_blacklisted
      owner = xcbq.Window(self.qtile.core.conn, owner_id)
  AttributeError: module 'libqtile.backend.x11.xcbq' has no attribute 'Window'
  ```
  
  </issue>
  <code>
  [start of libqtile/widget/clipboard.py]
  1 # Copyright (c) 2014 Sean Vig
  2 # Copyright (c) 2014 roger
  3 # Copyright (c) 2014 Adi Sieker
  4 # Copyright (c) 2014 Tycho Andersen
  5 #
  6 # Permission is hereby granted, free of charge, to any person obtaining a copy
  7 # of this software and associated documentation files (the "Software"), to deal
  8 # in the Software without restriction, including without limitation the rights
  9 # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10 # copies of the Software, and to permit persons to whom the Software is
  11 # furnished to do so, subject to the following conditions:
  12 #
  13 # The above copyright notice and this permission notice shall be included in
  14 # all copies or substantial portions of the Software.
  15 #
  16 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18 # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  19 # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20 # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  21 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  22 # SOFTWARE.
  23 
  24 from libqtile import bar, hook
  25 from libqtile.backend.x11 import xcbq
  26 from libqtile.widget import base
  27 
  28 
  29 class Clipboard(base._TextBox):
  30     """Display current clipboard contents"""
  31     orientations = base.ORIENTATION_HORIZONTAL
  32     defaults = [
  33         ("selection", "CLIPBOARD",
  34             "the selection to display(CLIPBOARD or PRIMARY)"),
  35         ("max_width", 10, "maximum number of characters to display "
  36             "(None for all, useful when width is bar.STRETCH)"),
  37         ("timeout", 10,
  38             "Default timeout (seconds) for display text, None to keep forever"),
  39         ("blacklist", ["keepassx"],
  40             "list with blacklisted wm_class, sadly not every "
  41             "clipboard window sets them, keepassx does."
  42             "Clipboard contents from blacklisted wm_classes "
  43             "will be replaced by the value of ``blacklist_text``."),
  44         ("blacklist_text", "***********",
  45             "text to display when the wm_class is blacklisted")
  46     ]
  47 
  48     def __init__(self, width=bar.CALCULATED, **config):
  49         base._TextBox.__init__(self, "", width, **config)
  50         self.add_defaults(Clipboard.defaults)
  51         self.timeout_id = None
  52 
  53     def _configure(self, qtile, bar):
  54         base._TextBox._configure(self, qtile, bar)
  55         self.text = ""
  56         self.setup_hooks()
  57 
  58     def clear(self, *args):
  59         self.text = ""
  60         self.bar.draw()
  61 
  62     def is_blacklisted(self, owner_id):
  63         if not self.blacklist:
  64             return False
  65 
  66         if owner_id in self.qtile.windows_map:
  67             owner = self.qtile.windows_map[owner_id].window
  68         else:
  69             owner = xcbq.Window(self.qtile.core.conn, owner_id)
  70 
  71         owner_class = owner.get_wm_class()
  72         if owner_class:
  73             for wm_class in self.blacklist:
  74                 if wm_class in owner_class:
  75                     return True
  76 
  77     def setup_hooks(self):
  78         def hook_change(name, selection):
  79             if name != self.selection:
  80                 return
  81 
  82             if self.is_blacklisted(selection["owner"]):
  83                 text = self.blacklist_text
  84             else:
  85                 text = selection["selection"].replace("\n", " ")
  86 
  87                 text = text.strip()
  88                 if self.max_width is not None and len(text) > self.max_width:
  89                     text = text[:self.max_width] + "..."
  90 
  91             self.text = text
  92 
  93             if self.timeout_id:
  94                 self.timeout_id.cancel()
  95                 self.timeout_id = None
  96 
  97             if self.timeout:
  98                 self.timeout_id = self.timeout_add(self.timeout, self.clear)
  99             self.bar.draw()
  100 
  101         def hook_notify(name, selection):
  102             if name != self.selection:
  103                 return
  104 
  105             if self.timeout_id:
  106                 self.timeout_id.cancel()
  107                 self.timeout_id = None
  108 
  109             # only clear if don't change don't apply in .5 seconds
  110             if self.timeout:
  111                 self.timeout_id = self.timeout_add(self.timeout, self.clear)
  112             self.bar.draw()
  113 
  114         hook.subscribe.selection_notify(hook_notify)
  115         hook.subscribe.selection_change(hook_change)
  116
  [end of libqtile/widget/clipboard.py]
  </code>
  
  I need you to solve this issue by generating a single patch file that I can apply directly to this repository using git apply. Please respond with a single patch file in the following format.
  <patch>
  diff --git a/file.py b/file.py
  --- a/file.py
  +++ b/file.py
  @@ -1,27 +1,35 @@
   def euclidean(a, b):
  -    while b:
  -        a, b = b, a % b
  -    return a
  +    if b == 0:
  +        return a
  +    return euclidean(b, a % b)
   
   
   def bresenham(x0, y0, x1, y1):
       points = []
       dx = abs(x1 - x0)
       dy = abs(y1 - y0)
  -    sx = 1 if x0 < x1 else -1
  -    sy = 1 if y0 < y1 else -1
  -    err = dx - dy
  +    x, y = x0, y0
  +    sx = -1 if x0 > x1 else 1
  +    sy = -1 if y0 > y1 else 1
   
  -    while True:
  -        points.append((x0, y0))
  -        if x0 == x1 and y0 == y1:
  -            break
  -        e2 = 2 * err
  -        if e2 > -dy:
  -            err -= dy
  -            x0 += sx
  -        if e2 < dx:
  -            err += dx
  -            y0 += sy
  +    if dx > dy:
  +        err = dx / 2.0
  +        while x != x1:
  +            points.append((x, y))
  +            err -= dy
  +            if err < 0:
  +                y += sy
  +                err += dx
  +            x += sx
  +    else:
  +        err = dy / 2.0
  +        while y != y1:
  +            points.append((x, y))
  +            err -= dx
  +            if err < 0:
  +                x += sx
  +                err += dy
  +            y += sy
  +
  +    points.append((x, y))
       return points
  
  </patch>
golden_diff: diff --git a/libqtile/widget/clipboard.py b/libqtile/widget/clipboard.py
  --- a/libqtile/widget/clipboard.py
  +++ b/libqtile/widget/clipboard.py
  @@ -66,7 +66,7 @@
           if owner_id in self.qtile.windows_map:
               owner = self.qtile.windows_map[owner_id].window
           else:
  -            owner = xcbq.Window(self.qtile.core.conn, owner_id)
  +            owner = xcbq.window.XWindow(self.qtile.core.conn, owner_id)
   
           owner_class = owner.get_wm_class()
           if owner_class:
  
verification_info: {"golden_diff": "diff --git a/libqtile/widget/clipboard.py b/libqtile/widget/clipboard.py\n--- a/libqtile/widget/clipboard.py\n+++ b/libqtile/widget/clipboard.py\n@@ -66,7 +66,7 @@\n         if owner_id in self.qtile.windows_map:\n             owner = self.qtile.windows_map[owner_id].window\n         else:\n-            owner = xcbq.Window(self.qtile.core.conn, owner_id)\n+            owner = xcbq.window.XWindow(self.qtile.core.conn, owner_id)\n \n         owner_class = owner.get_wm_class()\n         if owner_class:\n", "issue": "stack trace from Clipboard widget\n```\r\n2021-08-13 06:48:23,421 ERROR libqtile hook.py:fire():L381 Error in hook selection_change\r\nTraceback (most recent call last):\r\n  File \"/home/tycho/.local/lib/python3.9/site-packages/libqtile/hook.py\", line 379, in fire\r\n    i(*args, **kwargs)\r\n  File \"/home/tycho/.local/lib/python3.9/site-packages/libqtile/widget/clipboard.py\", line 82, in hook_change\r\n    if self.is_blacklisted(selection[\"owner\"]):\r\n  File \"/home/tycho/.local/lib/python3.9/site-packages/libqtile/widget/clipboard.py\", line 69, in is_blacklisted\r\n    owner = xcbq.Window(self.qtile.core.conn, owner_id)\r\nAttributeError: module 'libqtile.backend.x11.xcbq' has no attribute 'Window'\r\n```\n", "before_files": [{"content": "# Copyright (c) 2014 Sean Vig\n# Copyright (c) 2014 roger\n# Copyright (c) 2014 Adi Sieker\n# Copyright (c) 2014 Tycho Andersen\n#\n# Permission is hereby granted, free of charge, to any person obtaining a copy\n# of this software and associated documentation files (the \"Software\"), to deal\n# in the Software without restriction, including without limitation the rights\n# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n# copies of the Software, and to permit persons to whom the Software is\n# furnished to do so, subject to the following conditions:\n#\n# The above copyright notice and this permission notice shall be included in\n# all copies or substantial portions of the Software.\n#\n# THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n# SOFTWARE.\n\nfrom libqtile import bar, hook\nfrom libqtile.backend.x11 import xcbq\nfrom libqtile.widget import base\n\n\nclass Clipboard(base._TextBox):\n    \"\"\"Display current clipboard contents\"\"\"\n    orientations = base.ORIENTATION_HORIZONTAL\n    defaults = [\n        (\"selection\", \"CLIPBOARD\",\n            \"the selection to display(CLIPBOARD or PRIMARY)\"),\n        (\"max_width\", 10, \"maximum number of characters to display \"\n            \"(None for all, useful when width is bar.STRETCH)\"),\n        (\"timeout\", 10,\n            \"Default timeout (seconds) for display text, None to keep forever\"),\n        (\"blacklist\", [\"keepassx\"],\n            \"list with blacklisted wm_class, sadly not every \"\n            \"clipboard window sets them, keepassx does.\"\n            \"Clipboard contents from blacklisted wm_classes \"\n            \"will be replaced by the value of ``blacklist_text``.\"),\n        (\"blacklist_text\", \"***********\",\n            \"text to display when the wm_class is blacklisted\")\n    ]\n\n    def __init__(self, width=bar.CALCULATED, **config):\n        base._TextBox.__init__(self, \"\", width, **config)\n        self.add_defaults(Clipboard.defaults)\n        self.timeout_id = None\n\n    def _configure(self, qtile, bar):\n        base._TextBox._configure(self, qtile, bar)\n        self.text = \"\"\n        self.setup_hooks()\n\n    def clear(self, *args):\n        self.text = \"\"\n        self.bar.draw()\n\n    def is_blacklisted(self, owner_id):\n        if not self.blacklist:\n            return False\n\n        if owner_id in self.qtile.windows_map:\n            owner = self.qtile.windows_map[owner_id].window\n        else:\n            owner = xcbq.Window(self.qtile.core.conn, owner_id)\n\n        owner_class = owner.get_wm_class()\n        if owner_class:\n            for wm_class in self.blacklist:\n                if wm_class in owner_class:\n                    return True\n\n    def setup_hooks(self):\n        def hook_change(name, selection):\n            if name != self.selection:\n                return\n\n            if self.is_blacklisted(selection[\"owner\"]):\n                text = self.blacklist_text\n            else:\n                text = selection[\"selection\"].replace(\"\\n\", \" \")\n\n                text = text.strip()\n                if self.max_width is not None and len(text) > self.max_width:\n                    text = text[:self.max_width] + \"...\"\n\n            self.text = text\n\n            if self.timeout_id:\n                self.timeout_id.cancel()\n                self.timeout_id = None\n\n            if self.timeout:\n                self.timeout_id = self.timeout_add(self.timeout, self.clear)\n            self.bar.draw()\n\n        def hook_notify(name, selection):\n            if name != self.selection:\n                return\n\n            if self.timeout_id:\n                self.timeout_id.cancel()\n                self.timeout_id = None\n\n            # only clear if don't change don't apply in .5 seconds\n            if self.timeout:\n                self.timeout_id = self.timeout_add(self.timeout, self.clear)\n            self.bar.draw()\n\n        hook.subscribe.selection_notify(hook_notify)\n        hook.subscribe.selection_change(hook_change)\n", "path": "libqtile/widget/clipboard.py"}]}