diff --git a/config/ags/js/overview/main.js b/config/ags/js/overview/main.js
new file mode 100644
index 00000000..4ab88336
--- /dev/null
+++ b/config/ags/js/overview/main.js
@@ -0,0 +1,134 @@
+const { Window, Box, CenterBox, Icon } = ags.Widget;
+const { Hyprland, Applications } = ags.Service;
+const { Gtk } = imports.gi;
+
+import { EventBox } from '../misc/cursorbox.js';
+
+const SCALE = 0.11;
+const MARGIN = 8;
+
+export const Overview = Window({
+  name: 'overview',
+  layer: 'overlay',
+  //popup: true,
+  anchor: 'top',
+  margin: [ 0, 0, 0, 0 ],
+  child: Box({
+    className: 'overview',
+    vertical: true,
+    children: [
+      CenterBox({
+        children: [
+          null,
+          Box({
+            className: 'normal',
+          }),
+          null,
+        ],
+      }),
+      CenterBox({
+        children: [
+          null,
+          Box({
+            className: 'special',
+          }),
+          null,
+        ],
+      }),
+    ],
+    connections: [
+      [Hyprland, box => {
+        box._workspaces = box.children[0].centerWidget.children.concat(
+                         box.children[1].centerWidget.children)
+        let newWorkspaces = Hyprland.workspaces;
+
+        if (newWorkspaces.length > box._workspaces.length) {
+          box._updateWs(box);
+        }
+
+        if (box._canUpdate)
+          box._updateApps(box);
+
+      }],
+    ],
+    properties: [
+      ['canUpdate', true],
+      ['workspaces'],
+      ['clients'],
+
+      ['updateApps', box => {
+        ags.Utils.execAsync('hyprctl clients -j')
+        .then(result => {
+          box._clients = JSON.parse(result).filter(client => client.class)
+
+          box._workspaces.forEach(workspace => {
+            let fixed = workspace.children[0].child;
+            fixed.get_children().forEach(ch => ch.destroy());
+
+            box._clients.filter(app => app.workspace.id == workspace._id).forEach(app => {
+              let active = '';
+              if (app.address == Hyprland.active.client.address) {
+                active = 'active';
+              }
+
+              if (app.size[0] === 0) {
+                app.size[0] = 1524;
+                app.size[1] = 908;
+              }
+
+              fixed.put(
+                Icon({
+                  className: `window ${active}`,
+                  style: `min-width: ${app.size[0] * SCALE - MARGIN}px;
+                          min-height: ${app.size[1] * SCALE - MARGIN}px;`,
+                  icon: app.class,
+                  size: 40,
+                }),
+                app.at[0] * SCALE,
+                app.at[1] * SCALE
+              );
+            });
+            fixed.show_all();
+          });
+        }).catch(print);
+      }],
+
+      ['updateWs', box => {
+        if (!box._canUpdate)
+          return;
+
+        box._canUpdate = false;
+        const id = Hyprland.instance.connect('changed', () => {
+          Hyprland.workspaces.forEach(ws => {
+            if (box._workspaces.some(ch => ch._id == ws.id)) 
+              return;
+
+            var childI = 0;
+            if (ws.id < 0) {
+              childI = 1;
+            }
+
+            box.children[childI].centerWidget.add(
+              Box({
+                properties: [['id', ws.id]],
+                className: 'workspace',
+                child: EventBox({
+                  tooltipText: `Workspace: ${ws.id}`,
+                  child: ags.Widget({
+                    type: Gtk.Fixed,
+                  }),
+                }),
+              })
+            );
+          });
+          box.show_all();
+          if (box.children[0].centerWidget.children.length > 0) {
+            Hyprland.instance.disconnect(id);
+            box._canUpdate = true;
+            box._updateApps(box);
+          }
+        });
+      }],
+    ],
+  }),
+});
diff --git a/config/ags/scss/main.scss b/config/ags/scss/main.scss
index 2a8c9a4d..a555c9de 100644
--- a/config/ags/scss/main.scss
+++ b/config/ags/scss/main.scss
@@ -12,3 +12,4 @@
 @import "./widgets/date.scss";
 @import "./widgets/quick-settings.scss";
 @import "./widgets/player.scss";
+@import "./widgets/overview.scss";
diff --git a/config/ags/scss/widgets/overview.scss b/config/ags/scss/widgets/overview.scss
new file mode 100644
index 00000000..52e4d76f
--- /dev/null
+++ b/config/ags/scss/widgets/overview.scss
@@ -0,0 +1,40 @@
+.overview {
+  min-height: 1px;
+  min-width: 1px;
+
+  .workspace .window {
+    border-radius: 10px;
+
+  }
+
+  .normal {
+    margin-bottom: 5px;
+
+    .workspace {
+      margin: 0 10px;
+
+      .window {
+        border: 2px solid #411C6C;
+
+        &.active {
+          border: 2px solid purple;
+        }
+      }
+    }
+  }
+  .special {
+
+    .workspace {
+      margin: 0 5px;
+
+      .window {
+        border: 2px solid lighten($color: black, $amount: 20);
+
+        &.active {
+          border: 2px solid purple;
+        }
+
+      }
+    }
+  }
+}
diff --git a/config/ags/style.css b/config/ags/style.css
index de40c058..609d5f3a 100644
--- a/config/ags/style.css
+++ b/config/ags/style.css
@@ -664,3 +664,23 @@ calendar:indeterminate {
 
 .position-slider slider:hover {
   transition: background-color 0.5s ease-in-out; }
+
+.overview {
+  min-height: 1px;
+  min-width: 1px; }
+  .overview .workspace .window {
+    border-radius: 10px; }
+  .overview .normal {
+    margin-bottom: 5px; }
+    .overview .normal .workspace {
+      margin: 0 10px; }
+      .overview .normal .workspace .window {
+        border: 2px solid #411C6C; }
+        .overview .normal .workspace .window.active {
+          border: 2px solid purple; }
+  .overview .special .workspace {
+    margin: 0 5px; }
+    .overview .special .workspace .window {
+      border: 2px solid #333333; }
+      .overview .special .workspace .window.active {
+        border: 2px solid purple; }