We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Missing requirement in documentation for Volume widget
# Issue description
The Volume widget by default needs access to amixer, which is part of the package alsa-utils, unless the `get_volume_command` is manually set to something else by the user.

This is not mentioned in the documentation [http://docs.qtile.org/en/latest/manual/ref/widgets.html#volume](http://docs.qtile.org/en/latest/manual/ref/widgets.html#volume)

# Qtile version
0.16.1

# Stack traces
N/A

# Configuration
Irrelevant


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `libqtile/widget/volume.py`
Content:
```
1 # Copyright (c) 2010, 2012, 2014 roger
2 # Copyright (c) 2011 Kirk Strauser
3 # Copyright (c) 2011 Florian Mounier
4 # Copyright (c) 2011 Mounier Florian
5 # Copyright (c) 2011 Roger Duran
6 # Copyright (c) 2012-2015 Tycho Andersen
7 # Copyright (c) 2013 Tao Sauvage
8 # Copyright (c) 2013 Craig Barnes
9 # Copyright (c) 2014-2015 Sean Vig
10 # Copyright (c) 2014 Adi Sieker
11 # Copyright (c) 2014 dmpayton
12 # Copyright (c) 2014 Jody Frankowski
13 # Copyright (c) 2016 Christoph Lassner
14 #
15 # Permission is hereby granted, free of charge, to any person obtaining a copy
16 # of this software and associated documentation files (the "Software"), to deal
17 # in the Software without restriction, including without limitation the rights
18 # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
19 # copies of the Software, and to permit persons to whom the Software is
20 # furnished to do so, subject to the following conditions:
21 #
22 # The above copyright notice and this permission notice shall be included in
23 # all copies or substantial portions of the Software.
24 #
25 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
26 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
27 # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
28 # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
29 # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
30 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
31 # SOFTWARE.
32 
33 import re
34 import subprocess
35 
36 from libqtile import bar
37 from libqtile.widget import base
38 
39 __all__ = [
40     'Volume',
41 ]
42 
43 re_vol = re.compile(r'\[(\d?\d?\d?)%\]')
44 
45 
46 class Volume(base._TextBox):
47     """Widget that display and change volume
48 
49     If theme_path is set it draw widget as icons.
50     """
51     orientations = base.ORIENTATION_HORIZONTAL
52     defaults = [
53         ("cardid", None, "Card Id"),
54         ("device", "default", "Device Name"),
55         ("channel", "Master", "Channel"),
56         ("padding", 3, "Padding left and right. Calculated if None."),
57         ("update_interval", 0.2, "Update time in seconds."),
58         ("theme_path", None, "Path of the icons"),
59         ("emoji", False, "Use emoji to display volume states, only if ``theme_path`` is not set."
60                          "The specified font needs to contain the correct unicode characters."),
61         ("mute_command", None, "Mute command"),
62         ("volume_app", None, "App to control volume"),
63         ("volume_up_command", None, "Volume up command"),
64         ("volume_down_command", None, "Volume down command"),
65         ("get_volume_command", None, "Command to get the current volume"),
66         ("step", 2, "Volume change for up an down commands in percentage."
67                     "Only used if ``volume_up_command`` and ``volume_down_command`` are not set.")
68     ]
69 
70     def __init__(self, **config):
71         base._TextBox.__init__(self, '0', width=bar.CALCULATED, **config)
72         self.add_defaults(Volume.defaults)
73         if self.theme_path:
74             self.length_type = bar.STATIC
75             self.length = 0
76         self.surfaces = {}
77         self.volume = None
78 
79         self.add_callbacks({
80             'Button1': self.cmd_mute,
81             'Button3': self.cmd_run_app,
82             'Button4': self.cmd_increase_vol,
83             'Button5': self.cmd_decrease_vol,
84         })
85 
86     def timer_setup(self):
87         self.timeout_add(self.update_interval, self.update)
88         if self.theme_path:
89             self.setup_images()
90 
91     def create_amixer_command(self, *args):
92         cmd = ['amixer']
93 
94         if (self.cardid is not None):
95             cmd.extend(['-c', str(self.cardid)])
96 
97         if (self.device is not None):
98             cmd.extend(['-D', str(self.device)])
99 
100         cmd.extend([x for x in args])
101         return cmd
102 
103     def button_press(self, x, y, button):
104         base._TextBox.button_press(self, x, y, button)
105         self.draw()
106 
107     def update(self):
108         vol = self.get_volume()
109         if vol != self.volume:
110             self.volume = vol
111             # Update the underlying canvas size before actually attempting
112             # to figure out how big it is and draw it.
113             self._update_drawer()
114             self.bar.draw()
115         self.timeout_add(self.update_interval, self.update)
116 
117     def _update_drawer(self):
118         if self.theme_path:
119             self.drawer.clear(self.background or self.bar.background)
120             if self.volume <= 0:
121                 img_name = 'audio-volume-muted'
122             elif self.volume <= 30:
123                 img_name = 'audio-volume-low'
124             elif self.volume < 80:
125                 img_name = 'audio-volume-medium'
126             else:  # self.volume >= 80:
127                 img_name = 'audio-volume-high'
128 
129             self.drawer.ctx.set_source(self.surfaces[img_name])
130             self.drawer.ctx.paint()
131         elif self.emoji:
132             if self.volume <= 0:
133                 self.text = u'\U0001f507'
134             elif self.volume <= 30:
135                 self.text = u'\U0001f508'
136             elif self.volume < 80:
137                 self.text = u'\U0001f509'
138             elif self.volume >= 80:
139                 self.text = u'\U0001f50a'
140         else:
141             if self.volume == -1:
142                 self.text = 'M'
143             else:
144                 self.text = '{}%'.format(self.volume)
145 
146     def setup_images(self):
147         from libqtile import images
148         names = (
149             'audio-volume-high',
150             'audio-volume-low',
151             'audio-volume-medium',
152             'audio-volume-muted',
153         )
154         d_images = images.Loader(self.theme_path)(*names)
155         for name, img in d_images.items():
156             new_height = self.bar.height - 1
157             img.resize(height=new_height)
158             if img.width > self.length:
159                 self.length = img.width + self.actual_padding * 2
160             self.surfaces[name] = img.pattern
161 
162     def get_volume(self):
163         try:
164             get_volume_cmd = self.create_amixer_command('sget',
165                                                         self.channel)
166 
167             if self.get_volume_command:
168                 get_volume_cmd = self.get_volume_command
169 
170             mixer_out = self.call_process(get_volume_cmd)
171         except subprocess.CalledProcessError:
172             return -1
173 
174         if '[off]' in mixer_out:
175             return -1
176 
177         volgroups = re_vol.search(mixer_out)
178         if volgroups:
179             return int(volgroups.groups()[0])
180         else:
181             # this shouldn't happen
182             return -1
183 
184     def draw(self):
185         if self.theme_path:
186             self.drawer.draw(offsetx=self.offset, width=self.length)
187         else:
188             base._TextBox.draw(self)
189 
190     def cmd_increase_vol(self):
191         if self.volume_up_command is not None:
192             subprocess.call(self.volume_up_command, shell=True)
193         else:
194             subprocess.call(self.create_amixer_command('-q',
195                                                        'sset',
196                                                        self.channel,
197                                                        '{}%+'.format(self.step)))
198 
199     def cmd_decrease_vol(self):
200         if self.volume_down_command is not None:
201             subprocess.call(self.volume_down_command, shell=True)
202         else:
203             subprocess.call(self.create_amixer_command('-q',
204                                                        'sset',
205                                                        self.channel,
206                                                        '{}%-'.format(self.step)))
207 
208     def cmd_mute(self):
209         if self.mute_command is not None:
210             subprocess.call(self.mute_command, shell=True)
211         else:
212             subprocess.call(self.create_amixer_command('-q',
213                                                        'sset',
214                                                        self.channel,
215                                                        'toggle'))
216 
217     def cmd_run_app(self):
218         if self.volume_app is not None:
219             subprocess.Popen(self.volume_app, shell=True)
220
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/libqtile/widget/volume.py b/libqtile/widget/volume.py
--- a/libqtile/widget/volume.py
+++ b/libqtile/widget/volume.py
@@ -46,6 +46,10 @@
 class Volume(base._TextBox):
     """Widget that display and change volume
 
+    By default, this widget uses ``amixer`` to get and set the volume so users
+    will need to make sure this is installed. Alternatively, users may set the
+    relevant parameters for the widget to use a different application.
+
     If theme_path is set it draw widget as icons.
     """
     orientations = base.ORIENTATION_HORIZONTAL

{"golden_diff": "diff --git a/libqtile/widget/volume.py b/libqtile/widget/volume.py\n--- a/libqtile/widget/volume.py\n+++ b/libqtile/widget/volume.py\n@@ -46,6 +46,10 @@\n class Volume(base._TextBox):\n     \"\"\"Widget that display and change volume\n \n+    By default, this widget uses ``amixer`` to get and set the volume so users\n+    will need to make sure this is installed. Alternatively, users may set the\n+    relevant parameters for the widget to use a different application.\n+\n     If theme_path is set it draw widget as icons.\n     \"\"\"\n     orientations = base.ORIENTATION_HORIZONTAL\n", "issue": "Missing requirement in documentation for Volume widget\n# Issue description\r\nThe Volume widget by default needs access to amixer, which is part of the package alsa-utils, unless the `get_volume_command` is manually set to something else by the user.\r\n\r\nThis is not mentioned in the documentation [http://docs.qtile.org/en/latest/manual/ref/widgets.html#volume](http://docs.qtile.org/en/latest/manual/ref/widgets.html#volume)\r\n\r\n# Qtile version\r\n0.16.1\r\n\r\n# Stack traces\r\nN/A\r\n\r\n# Configuration\r\nIrrelevant\r\n\n", "before_files": [{"content": "# Copyright (c) 2010, 2012, 2014 roger\n# Copyright (c) 2011 Kirk Strauser\n# Copyright (c) 2011 Florian Mounier\n# Copyright (c) 2011 Mounier Florian\n# Copyright (c) 2011 Roger Duran\n# Copyright (c) 2012-2015 Tycho Andersen\n# Copyright (c) 2013 Tao Sauvage\n# Copyright (c) 2013 Craig Barnes\n# Copyright (c) 2014-2015 Sean Vig\n# Copyright (c) 2014 Adi Sieker\n# Copyright (c) 2014 dmpayton\n# Copyright (c) 2014 Jody Frankowski\n# Copyright (c) 2016 Christoph Lassner\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\nimport re\nimport subprocess\n\nfrom libqtile import bar\nfrom libqtile.widget import base\n\n__all__ = [\n    'Volume',\n]\n\nre_vol = re.compile(r'\\[(\\d?\\d?\\d?)%\\]')\n\n\nclass Volume(base._TextBox):\n    \"\"\"Widget that display and change volume\n\n    If theme_path is set it draw widget as icons.\n    \"\"\"\n    orientations = base.ORIENTATION_HORIZONTAL\n    defaults = [\n        (\"cardid\", None, \"Card Id\"),\n        (\"device\", \"default\", \"Device Name\"),\n        (\"channel\", \"Master\", \"Channel\"),\n        (\"padding\", 3, \"Padding left and right. Calculated if None.\"),\n        (\"update_interval\", 0.2, \"Update time in seconds.\"),\n        (\"theme_path\", None, \"Path of the icons\"),\n        (\"emoji\", False, \"Use emoji to display volume states, only if ``theme_path`` is not set.\"\n                         \"The specified font needs to contain the correct unicode characters.\"),\n        (\"mute_command\", None, \"Mute command\"),\n        (\"volume_app\", None, \"App to control volume\"),\n        (\"volume_up_command\", None, \"Volume up command\"),\n        (\"volume_down_command\", None, \"Volume down command\"),\n        (\"get_volume_command\", None, \"Command to get the current volume\"),\n        (\"step\", 2, \"Volume change for up an down commands in percentage.\"\n                    \"Only used if ``volume_up_command`` and ``volume_down_command`` are not set.\")\n    ]\n\n    def __init__(self, **config):\n        base._TextBox.__init__(self, '0', width=bar.CALCULATED, **config)\n        self.add_defaults(Volume.defaults)\n        if self.theme_path:\n            self.length_type = bar.STATIC\n            self.length = 0\n        self.surfaces = {}\n        self.volume = None\n\n        self.add_callbacks({\n            'Button1': self.cmd_mute,\n            'Button3': self.cmd_run_app,\n            'Button4': self.cmd_increase_vol,\n            'Button5': self.cmd_decrease_vol,\n        })\n\n    def timer_setup(self):\n        self.timeout_add(self.update_interval, self.update)\n        if self.theme_path:\n            self.setup_images()\n\n    def create_amixer_command(self, *args):\n        cmd = ['amixer']\n\n        if (self.cardid is not None):\n            cmd.extend(['-c', str(self.cardid)])\n\n        if (self.device is not None):\n            cmd.extend(['-D', str(self.device)])\n\n        cmd.extend([x for x in args])\n        return cmd\n\n    def button_press(self, x, y, button):\n        base._TextBox.button_press(self, x, y, button)\n        self.draw()\n\n    def update(self):\n        vol = self.get_volume()\n        if vol != self.volume:\n            self.volume = vol\n            # Update the underlying canvas size before actually attempting\n            # to figure out how big it is and draw it.\n            self._update_drawer()\n            self.bar.draw()\n        self.timeout_add(self.update_interval, self.update)\n\n    def _update_drawer(self):\n        if self.theme_path:\n            self.drawer.clear(self.background or self.bar.background)\n            if self.volume <= 0:\n                img_name = 'audio-volume-muted'\n            elif self.volume <= 30:\n                img_name = 'audio-volume-low'\n            elif self.volume < 80:\n                img_name = 'audio-volume-medium'\n            else:  # self.volume >= 80:\n                img_name = 'audio-volume-high'\n\n            self.drawer.ctx.set_source(self.surfaces[img_name])\n            self.drawer.ctx.paint()\n        elif self.emoji:\n            if self.volume <= 0:\n                self.text = u'\\U0001f507'\n            elif self.volume <= 30:\n                self.text = u'\\U0001f508'\n            elif self.volume < 80:\n                self.text = u'\\U0001f509'\n            elif self.volume >= 80:\n                self.text = u'\\U0001f50a'\n        else:\n            if self.volume == -1:\n                self.text = 'M'\n            else:\n                self.text = '{}%'.format(self.volume)\n\n    def setup_images(self):\n        from libqtile import images\n        names = (\n            'audio-volume-high',\n            'audio-volume-low',\n            'audio-volume-medium',\n            'audio-volume-muted',\n        )\n        d_images = images.Loader(self.theme_path)(*names)\n        for name, img in d_images.items():\n            new_height = self.bar.height - 1\n            img.resize(height=new_height)\n            if img.width > self.length:\n                self.length = img.width + self.actual_padding * 2\n            self.surfaces[name] = img.pattern\n\n    def get_volume(self):\n        try:\n            get_volume_cmd = self.create_amixer_command('sget',\n                                                        self.channel)\n\n            if self.get_volume_command:\n                get_volume_cmd = self.get_volume_command\n\n            mixer_out = self.call_process(get_volume_cmd)\n        except subprocess.CalledProcessError:\n            return -1\n\n        if '[off]' in mixer_out:\n            return -1\n\n        volgroups = re_vol.search(mixer_out)\n        if volgroups:\n            return int(volgroups.groups()[0])\n        else:\n            # this shouldn't happen\n            return -1\n\n    def draw(self):\n        if self.theme_path:\n            self.drawer.draw(offsetx=self.offset, width=self.length)\n        else:\n            base._TextBox.draw(self)\n\n    def cmd_increase_vol(self):\n        if self.volume_up_command is not None:\n            subprocess.call(self.volume_up_command, shell=True)\n        else:\n            subprocess.call(self.create_amixer_command('-q',\n                                                       'sset',\n                                                       self.channel,\n                                                       '{}%+'.format(self.step)))\n\n    def cmd_decrease_vol(self):\n        if self.volume_down_command is not None:\n            subprocess.call(self.volume_down_command, shell=True)\n        else:\n            subprocess.call(self.create_amixer_command('-q',\n                                                       'sset',\n                                                       self.channel,\n                                                       '{}%-'.format(self.step)))\n\n    def cmd_mute(self):\n        if self.mute_command is not None:\n            subprocess.call(self.mute_command, shell=True)\n        else:\n            subprocess.call(self.create_amixer_command('-q',\n                                                       'sset',\n                                                       self.channel,\n                                                       'toggle'))\n\n    def cmd_run_app(self):\n        if self.volume_app is not None:\n            subprocess.Popen(self.volume_app, shell=True)\n", "path": "libqtile/widget/volume.py"}], "after_files": [{"content": "# Copyright (c) 2010, 2012, 2014 roger\n# Copyright (c) 2011 Kirk Strauser\n# Copyright (c) 2011 Florian Mounier\n# Copyright (c) 2011 Mounier Florian\n# Copyright (c) 2011 Roger Duran\n# Copyright (c) 2012-2015 Tycho Andersen\n# Copyright (c) 2013 Tao Sauvage\n# Copyright (c) 2013 Craig Barnes\n# Copyright (c) 2014-2015 Sean Vig\n# Copyright (c) 2014 Adi Sieker\n# Copyright (c) 2014 dmpayton\n# Copyright (c) 2014 Jody Frankowski\n# Copyright (c) 2016 Christoph Lassner\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\nimport re\nimport subprocess\n\nfrom libqtile import bar\nfrom libqtile.widget import base\n\n__all__ = [\n    'Volume',\n]\n\nre_vol = re.compile(r'\\[(\\d?\\d?\\d?)%\\]')\n\n\nclass Volume(base._TextBox):\n    \"\"\"Widget that display and change volume\n\n    By default, this widget uses ``amixer`` to get and set the volume so users\n    will need to make sure this is installed. Alternatively, users may set the\n    relevant parameters for the widget to use a different application.\n\n    If theme_path is set it draw widget as icons.\n    \"\"\"\n    orientations = base.ORIENTATION_HORIZONTAL\n    defaults = [\n        (\"cardid\", None, \"Card Id\"),\n        (\"device\", \"default\", \"Device Name\"),\n        (\"channel\", \"Master\", \"Channel\"),\n        (\"padding\", 3, \"Padding left and right. Calculated if None.\"),\n        (\"update_interval\", 0.2, \"Update time in seconds.\"),\n        (\"theme_path\", None, \"Path of the icons\"),\n        (\"emoji\", False, \"Use emoji to display volume states, only if ``theme_path`` is not set.\"\n                         \"The specified font needs to contain the correct unicode characters.\"),\n        (\"mute_command\", None, \"Mute command\"),\n        (\"volume_app\", None, \"App to control volume\"),\n        (\"volume_up_command\", None, \"Volume up command\"),\n        (\"volume_down_command\", None, \"Volume down command\"),\n        (\"get_volume_command\", None, \"Command to get the current volume\"),\n        (\"step\", 2, \"Volume change for up an down commands in percentage.\"\n                    \"Only used if ``volume_up_command`` and ``volume_down_command`` are not set.\")\n    ]\n\n    def __init__(self, **config):\n        base._TextBox.__init__(self, '0', width=bar.CALCULATED, **config)\n        self.add_defaults(Volume.defaults)\n        if self.theme_path:\n            self.length_type = bar.STATIC\n            self.length = 0\n        self.surfaces = {}\n        self.volume = None\n\n        self.add_callbacks({\n            'Button1': self.cmd_mute,\n            'Button3': self.cmd_run_app,\n            'Button4': self.cmd_increase_vol,\n            'Button5': self.cmd_decrease_vol,\n        })\n\n    def timer_setup(self):\n        self.timeout_add(self.update_interval, self.update)\n        if self.theme_path:\n            self.setup_images()\n\n    def create_amixer_command(self, *args):\n        cmd = ['amixer']\n\n        if (self.cardid is not None):\n            cmd.extend(['-c', str(self.cardid)])\n\n        if (self.device is not None):\n            cmd.extend(['-D', str(self.device)])\n\n        cmd.extend([x for x in args])\n        return cmd\n\n    def button_press(self, x, y, button):\n        base._TextBox.button_press(self, x, y, button)\n        self.draw()\n\n    def update(self):\n        vol = self.get_volume()\n        if vol != self.volume:\n            self.volume = vol\n            # Update the underlying canvas size before actually attempting\n            # to figure out how big it is and draw it.\n            self._update_drawer()\n            self.bar.draw()\n        self.timeout_add(self.update_interval, self.update)\n\n    def _update_drawer(self):\n        if self.theme_path:\n            self.drawer.clear(self.background or self.bar.background)\n            if self.volume <= 0:\n                img_name = 'audio-volume-muted'\n            elif self.volume <= 30:\n                img_name = 'audio-volume-low'\n            elif self.volume < 80:\n                img_name = 'audio-volume-medium'\n            else:  # self.volume >= 80:\n                img_name = 'audio-volume-high'\n\n            self.drawer.ctx.set_source(self.surfaces[img_name])\n            self.drawer.ctx.paint()\n        elif self.emoji:\n            if self.volume <= 0:\n                self.text = u'\\U0001f507'\n            elif self.volume <= 30:\n                self.text = u'\\U0001f508'\n            elif self.volume < 80:\n                self.text = u'\\U0001f509'\n            elif self.volume >= 80:\n                self.text = u'\\U0001f50a'\n        else:\n            if self.volume == -1:\n                self.text = 'M'\n            else:\n                self.text = '{}%'.format(self.volume)\n\n    def setup_images(self):\n        from libqtile import images\n        names = (\n            'audio-volume-high',\n            'audio-volume-low',\n            'audio-volume-medium',\n            'audio-volume-muted',\n        )\n        d_images = images.Loader(self.theme_path)(*names)\n        for name, img in d_images.items():\n            new_height = self.bar.height - 1\n            img.resize(height=new_height)\n            if img.width > self.length:\n                self.length = img.width + self.actual_padding * 2\n            self.surfaces[name] = img.pattern\n\n    def get_volume(self):\n        try:\n            get_volume_cmd = self.create_amixer_command('sget',\n                                                        self.channel)\n\n            if self.get_volume_command:\n                get_volume_cmd = self.get_volume_command\n\n            mixer_out = self.call_process(get_volume_cmd)\n        except subprocess.CalledProcessError:\n            return -1\n\n        if '[off]' in mixer_out:\n            return -1\n\n        volgroups = re_vol.search(mixer_out)\n        if volgroups:\n            return int(volgroups.groups()[0])\n        else:\n            # this shouldn't happen\n            return -1\n\n    def draw(self):\n        if self.theme_path:\n            self.drawer.draw(offsetx=self.offset, width=self.length)\n        else:\n            base._TextBox.draw(self)\n\n    def cmd_increase_vol(self):\n        if self.volume_up_command is not None:\n            subprocess.call(self.volume_up_command, shell=True)\n        else:\n            subprocess.call(self.create_amixer_command('-q',\n                                                       'sset',\n                                                       self.channel,\n                                                       '{}%+'.format(self.step)))\n\n    def cmd_decrease_vol(self):\n        if self.volume_down_command is not None:\n            subprocess.call(self.volume_down_command, shell=True)\n        else:\n            subprocess.call(self.create_amixer_command('-q',\n                                                       'sset',\n                                                       self.channel,\n                                                       '{}%-'.format(self.step)))\n\n    def cmd_mute(self):\n        if self.mute_command is not None:\n            subprocess.call(self.mute_command, shell=True)\n        else:\n            subprocess.call(self.create_amixer_command('-q',\n                                                       'sset',\n                                                       self.channel,\n                                                       'toggle'))\n\n    def cmd_run_app(self):\n        if self.volume_app is not None:\n            subprocess.Popen(self.volume_app, shell=True)\n", "path": "libqtile/widget/volume.py"}]}