diff --git a/scripts/volume.js b/scripts/volume.js
--- a/scripts/volume.js
+++ b/scripts/volume.js
@@ -1,3 +1,4 @@
+/* jshint esversion: 6 */
 /*
  * A widget to show and control the system volume.
  *
@@ -6,17 +7,20 @@
 define(['jquery', './socket'], function ($, socket) {
   "use strict";
 
-  var UID_RE = /Uid:\t(\d+)/;
+  const UID_RE = /Uid:\t(\d+)/;
 
-  var VOLUME_RE = /set-sink-volume.+ ([^ \n]+)/;
-  var MUTE_RE = /set-sink-mute.+ ([^ \n]+)/;
+  const VOLUME_RE = /set-sink-volume.+ ([^ \n]+)/;
+  const MUTE_RE = /set-sink-mute.+ ([^ \n]+)/;
 
-  var MAX_VOLUME = 0x10000;
+  const MAX_VOLUME = 0x10000;
 
-  var WAVES = 5;
+  const WIDTH = 25;
+  const HEIGHT = 25;
 
-  var self = {};
+  const WAVES = 5;
 
+  const self = {};
+
   self.settings_command = 'gnome-control-center sound &';
 
   function uid() {
@@ -26,6 +30,79 @@
     });
   }
 
+  self.widget = () => $('.widget-volume');
+
+  self.display = function () {
+    const widget = self.widget();
+
+    const canvas = $('<canvas />').attr({
+      width: WIDTH,
+      height: HEIGHT
+    });
+
+    widget.empty();
+    widget.append(canvas);
+
+    const context = canvas[0].getContext('2d');
+
+    const middle = WIDTH / 2 - 2;
+
+    const speakerBaseH = 5;
+    const speakerBaseW = 4;
+    const speakerW = 5;
+    const speakerH = 13;
+
+    const spacing = 2;
+
+    const crossSize = 6;
+
+    // Draw a speaker
+    context.beginPath();
+    context.moveTo(0, middle - speakerBaseH / 2);
+    context.lineTo(0, middle + speakerBaseH / 2);
+    context.lineTo(speakerBaseW, middle + speakerBaseH / 2);
+    context.lineTo(speakerBaseW + speakerW, middle + speakerH / 2);
+    context.lineTo(speakerBaseW + speakerW, middle - speakerH / 2);
+    context.lineTo(speakerBaseW, middle - speakerBaseH / 2);
+    context.lineTo(0, middle - speakerBaseH / 2);
+    context.fill();
+
+    if (self.mute) {
+      // Draw a cross
+      const crossLeft = speakerBaseW + speakerW + spacing;
+
+      context.save();
+      context.lineWidth = 1.5;
+
+      context.beginPath();
+      context.moveTo(crossLeft, middle - crossSize / 2);
+      context.lineTo(crossLeft + crossSize, middle + crossSize / 2);
+      context.stroke();
+
+      context.beginPath();
+      context.moveTo(crossLeft + crossSize, middle - crossSize / 2);
+      context.lineTo(crossLeft, middle + crossSize / 2);
+      context.stroke();
+
+      context.restore();
+    } else {
+      // Draw waves
+      const waveAngle = Math.PI / 6;
+      for (var i = 0; i < self.volume * WAVES; i ++) {
+        context.beginPath();
+        context.arc(
+          0, middle,
+          speakerBaseW + speakerW + spacing + 3 * i,
+          waveAngle / 2, -waveAngle / 2,
+          true);
+        context.stroke();
+      }
+    }
+
+    const percentage = self.volume.toFixed(2) * 100;
+    widget.attr('title', percentage + '%');
+  };
+
   $.when(
     $.ajax('tianbar:///execute', {
       data: {
@@ -37,65 +114,13 @@
     return socket('/var/run/user/' + uid + '/pulse/cli');
   }).then(function (pulseSocket) {
     pulseSocket.recv.add(function (dump) {
-      var mute = MUTE_RE.exec(dump)[1] === "yes";
-      var volume = parseInt(VOLUME_RE.exec(dump)[1], 16) / MAX_VOLUME;
-
-      var widget = $('.widget-volume');
-      widget.empty();
-
-      var speaker = $('<div />').css({
-        'float': 'left',
-        'border-top': '4px solid transparent',
-        'border-bottom': '4px solid transparent',
-        'border-right': '5px solid black',
-        'margin-top': 5,
-        'margin-bottom': 5,
-        'margin-right': 2
-      }).append($('<div />').css({
-        'background': 'black',
-        'width': 4,
-        'height': 5
-      }));
-      widget.append(speaker);
-
-      var waves = $('<div />').css({
-        'float': 'left',
-        'height': '100%',
-        'margin-top': 5,
-        'margin-bottom': 5,
-        'width': 12
-      });
-      if (mute) {
-        waves.append('x');
-      } else {
-        for (var i = 0; i < volume * WAVES; i ++) {
-          var waveSize = 6 + i * 2;
-          var margin = 10 - waveSize / 2;
-          var wave = $('<div />').css({
-            'display': 'inline-block',
-            'width': 1,
-            'height': waveSize,
-            'margin': 1,
-            'background': 'black',
-            'margin-bottom': margin
-          });
-          waves.append(wave);
-        }
-      }
-      widget.append(waves);
+      self.mute = MUTE_RE.exec(dump)[1] === "yes";
+      self.volume = parseInt(VOLUME_RE.exec(dump)[1], 16) / MAX_VOLUME;
 
-      var percentage = volume.toFixed(2) * 100;
-      widget.attr('title', percentage + '%');
+      self.display();
 
       window.setTimeout(requestDump, 1000);
 
-      widget.click(function () {
-        $.ajax('tianbar:///execute', {
-          data: {
-            command: self.settings_command
-          }
-        });
-      });
     });
 
     function requestDump () {
@@ -103,6 +128,16 @@
     }
 
     requestDump();
+  });
+
+  $(document).ready(function () {
+    self.widget().click(function () {
+      $.ajax('tianbar:///execute', {
+        data: {
+          command: self.settings_command
+        }
+      });
+    });
   });
 
   return self;
diff --git a/src/System/Tianbar.hs b/src/System/Tianbar.hs
--- a/src/System/Tianbar.hs
+++ b/src/System/Tianbar.hs
@@ -20,6 +20,7 @@
 import System.Tianbar.StrutProperties
 import System.Tianbar.WebKit
 
+
 topStrut :: Rectangle -> IO StrutProperties
 topStrut rect = do
     mX <- rectangleReadX rect
@@ -30,6 +31,30 @@
         h = barHeight + fromIntegral mY
      in return (0, 0, h, 0, 0, 0, 0, 0, x, x + w, 0, 0)
 
+
+sizeMainWindow :: Window -> IO ()
+sizeMainWindow window = do
+    Just disp <- displayGetDefault
+    screen <- displayGetDefaultScreen disp
+    monitorSize <- screenGetMonitorGeometry screen (fromIntegral myMonitor)
+
+    monitorX <- rectangleReadX monitorSize
+    monitorY <- rectangleReadY monitorSize
+    monitorW <- rectangleReadWidth monitorSize
+
+    let windowX = monitorX
+    let windowY = monitorY
+    let windowWidth = fromIntegral monitorW
+    let windowHeight = fromIntegral barHeight
+
+    windowSetDefaultSize window (fromIntegral monitorW) (fromIntegral barHeight)
+    windowMove window windowX windowY
+    windowResize window windowWidth windowHeight
+
+    strut <- topStrut monitorSize
+    setStrutProperties window strut
+
+
 main :: IO ()
 main = do
     progName <- getProgName
@@ -38,20 +63,15 @@
 
     Just disp <- displayGetDefault
     screen <- displayGetDefaultScreen disp
-    monitorSize <- screenGetMonitorGeometry screen (fromIntegral myMonitor)
 
     window <- windowNew WindowTypeToplevel
     widgetSetName window $ T.pack appName
 
-    monitorX <- rectangleReadX monitorSize
-    monitorW <- rectangleReadWidth monitorSize
     windowSetTypeHint window WindowTypeHintDock
     windowSetScreen window screen
-    windowSetDefaultSize window (fromIntegral monitorW) (fromIntegral barHeight)
-    strut <- topStrut monitorSize
-    windowMove window monitorX 0
-    _ <- onWidgetRealize window $
-        setStrutProperties window strut
+
+    _ <- onWidgetRealize window $ sizeMainWindow window
+    _ <- onScreenMonitorsChanged screen $ sizeMainWindow window
 
     box <- boxNew OrientationHorizontal 0
     containerAdd window box
diff --git a/tianbar.cabal b/tianbar.cabal
--- a/tianbar.cabal
+++ b/tianbar.cabal
@@ -1,5 +1,5 @@
 name:                tianbar
-version:             1.0.2.0
+version:             1.0.3.0
 synopsis:            A desktop bar based on WebKit
 description:
   A desktop bar using WebKit for rendering as much as possible.
