diff --git a/NEWS b/NEWS
index 434dcd4..11fbe6d 100644
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,16 @@
+3.38.2
+======
+* window-list: Honor changes in skip-taskbar property [Sergio; !130]
+* window-list, workspace-indicator: Improve previews in workspace thumbs
+  [Florian; #260, !142]
+* window-list, workspace-indicator: Adjust to 3.38 changes [Florian; !133]
+* auto-move: Improve behavior on multi-monitor setups [Florian; !135]
+* windowNavigator: Adjust to 3.38 changes [Thun; #259]
+* Misc. bug fixes [Ray; !145]
+
+Contributors:
+  Sergio Costas, Florian Müllner, Thun Pin, Ray Strode
+
 3.38.1
 ======
 
diff --git a/data/gnome-shell-sass/widgets/_app-grid.scss b/data/gnome-shell-sass/widgets/_app-grid.scss
index c183cfe..c98980e 100644
--- a/data/gnome-shell-sass/widgets/_app-grid.scss
+++ b/data/gnome-shell-sass/widgets/_app-grid.scss
@@ -8,6 +8,10 @@ $app_icon_size: 96px;
   column-spacing: $base_spacing * 6;
   max-row-spacing: $base_spacing * 12;
   max-column-spacing: $base_spacing * 12;
+  page-padding-top: $base_padding * 6;
+  page-padding-bottom: $base_padding * 6;
+  page-padding-left: $base_padding * 6;
+  page-padding-right: $base_padding * 6;
 }
 
 /* App Icons */
@@ -71,6 +75,10 @@ $app_grid_fg_color: #fff;
   & .icon-grid {
     row-spacing: $base_spacing * 2;
     column-spacing: $base_spacing * 5;
+    page-padding-top: 0;
+    page-padding-bottom: 0;
+    page-padding-left: 0;
+    page-padding-right: 0;
   }
 
   & .page-indicators {
diff --git a/data/gnome-shell-sass/widgets/_dialogs.scss b/data/gnome-shell-sass/widgets/_dialogs.scss
index fc77920..0f568b7 100644
--- a/data/gnome-shell-sass/widgets/_dialogs.scss
+++ b/data/gnome-shell-sass/widgets/_dialogs.scss
@@ -135,10 +135,6 @@
   spacing: 8px;
   margin-bottom: 6px;
 
-  .polkit-dialog-user-icon {
-    border-radius: 99px;
-    background-size: contain;
-  }
   .polkit-dialog-user-root-label { color: $warning_color; }
 }
 
diff --git a/extensions/auto-move-windows/extension.js b/extensions/auto-move-windows/extension.js
index d99244c..b9bc3a0 100644
--- a/extensions/auto-move-windows/extension.js
+++ b/extensions/auto-move-windows/extension.js
@@ -116,10 +116,12 @@ function myCheckWorkspaces() {
     let keepAliveWorkspaces = [];
     let foundNonEmpty = false;
     for (let i = this._workspaces.length - 1; i >= 0; i--) {
-        if (!foundNonEmpty)
-            foundNonEmpty = this._workspaces[i].list_windows().length > 0;
-        else if (!this._workspaces[i]._keepAliveId)
+        if (!foundNonEmpty) {
+            foundNonEmpty = this._workspaces[i].list_windows().some(
+                w => !w.is_on_all_workspaces());
+        } else if (!this._workspaces[i]._keepAliveId) {
             keepAliveWorkspaces.push(this._workspaces[i]);
+        }
     }
 
     // make sure the original method only removes empty workspaces at the end
diff --git a/extensions/window-list/extension.js b/extensions/window-list/extension.js
index 523ffb2..8babbae 100644
--- a/extensions/window-list/extension.js
+++ b/extensions/window-list/extension.js
@@ -352,6 +352,9 @@ class WindowButton extends BaseButton {
         super._init(perMonitor, monitorIndex);
 
         this.metaWindow = metaWindow;
+        this._skipTaskbarId = metaWindow.connect('notify::skip-taskbar', () => {
+            this._updateVisibility();
+        });
         this._updateVisibility();
 
         this._windowTitle = new WindowTitle(this.metaWindow);
@@ -412,6 +415,7 @@ class WindowButton extends BaseButton {
 
     _onDestroy() {
         super._onDestroy();
+        this.metaWindow.disconnect(this._skipTaskbarId);
         this.metaWindow.disconnect(this._workspaceChangedId);
         global.display.disconnect(this._notifyFocusId);
         this._contextMenu.destroy();
@@ -783,9 +787,9 @@ class WindowList extends St.Widget {
             });
 
         this._dragBeginId = Main.xdndHandler.connect('drag-begin',
-            this._onDragBegin.bind(this));
+            this._monitorDrag.bind(this));
         this._dragEndId = Main.xdndHandler.connect('drag-end',
-            this._onDragEnd.bind(this));
+            this._stopMonitoringDrag.bind(this));
         this._dragMonitor = {
             dragMotion: this._onDragMotion.bind(this),
         };
@@ -948,9 +952,6 @@ class WindowList extends St.Widget {
     }
 
     _onWindowAdded(ws, win) {
-        if (win.skip_taskbar)
-            return;
-
         if (!this._grouped)
             this._checkGrouping();
 
@@ -1016,11 +1017,11 @@ class WindowList extends St.Widget {
         }
     }
 
-    _onDragBegin() {
+    _monitorDrag() {
         DND.addDragMonitor(this._dragMonitor);
     }
 
-    _onDragEnd() {
+    _stopMonitoringDrag() {
         DND.removeDragMonitor(this._dragMonitor);
         this._removeActivateTimeout();
     }
@@ -1094,6 +1095,7 @@ class WindowList extends St.Widget {
 
         global.display.disconnect(this._fullscreenChangedId);
 
+        this._stopMonitoringDrag();
         Main.xdndHandler.disconnect(this._dragBeginId);
         Main.xdndHandler.disconnect(this._dragEndId);
 
diff --git a/extensions/window-list/workspaceIndicator.js b/extensions/window-list/workspaceIndicator.js
index ca3dc61..37d1ff0 100644
--- a/extensions/window-list/workspaceIndicator.js
+++ b/extensions/window-list/workspaceIndicator.js
@@ -24,27 +24,14 @@ class WindowPreview extends St.Button {
         this.connect('destroy', this._onDestroy.bind(this));
 
         this._sizeChangedId = this._window.connect('size-changed',
-            this._relayout.bind(this));
+            () => this.queue_relayout());
         this._positionChangedId = this._window.connect('position-changed',
-            this._relayout.bind(this));
-        this._minimizedChangedId = this._window.connect('notify::minimized',
-            this._relayout.bind(this));
-        this._monitorEnteredId = global.display.connect('window-entered-monitor',
-            this._relayout.bind(this));
-        this._monitorLeftId = global.display.connect('window-left-monitor',
-            this._relayout.bind(this));
-
-        // Do initial layout when we get a parent
-        let id = this.connect('parent-set', () => {
-            this.disconnect(id);
-            if (!this.get_parent())
-                return;
-            this._laterId = Meta.later_add(Meta.LaterType.BEFORE_REDRAW, () => {
-                this._laterId = 0;
-                this._relayout();
-                return false;
+            () => {
+                this._updateVisible();
+                this.queue_relayout();
             });
-        });
+        this._minimizedChangedId = this._window.connect('notify::minimized',
+            this._updateVisible.bind(this));
 
         this._focusChangedId = global.display.connect('notify::focus-window',
             this._onFocusChanged.bind(this));
@@ -52,19 +39,15 @@ class WindowPreview extends St.Button {
     }
 
     // needed for DND
-    get realWindow() {
-        return this._window.get_compositor_private();
+    get metaWindow() {
+        return this._window;
     }
 
     _onDestroy() {
         this._window.disconnect(this._sizeChangedId);
         this._window.disconnect(this._positionChangedId);
         this._window.disconnect(this._minimizedChangedId);
-        global.display.disconnect(this._monitorEnteredId);
-        global.display.disconnect(this._monitorLeftId);
         global.display.disconnect(this._focusChangedId);
-        if (this._laterId)
-            Meta.later_remove(this._laterId);
     }
 
     _onFocusChanged() {
@@ -74,26 +57,42 @@ class WindowPreview extends St.Button {
             this.remove_style_class_name('active');
     }
 
-    _relayout() {
-        let monitor = Main.layoutManager.findIndexForActor(this);
-        this.visible = monitor === this._window.get_monitor() &&
+    _updateVisible() {
+        const monitor = Main.layoutManager.findIndexForActor(this);
+        const workArea = Main.layoutManager.getWorkAreaForMonitor(monitor);
+        this.visible = this._window.get_frame_rect().overlap(workArea) &&
             this._window.window_type !== Meta.WindowType.DESKTOP &&
             this._window.showing_on_its_workspace();
+    }
+});
 
-        if (!this.visible)
-            return;
+let WorkspaceLayout = GObject.registerClass(
+class WorkspaceLayout extends Clutter.LayoutManager {
+    vfunc_get_preferred_width() {
+        return [0, 0];
+    }
 
-        let workArea = Main.layoutManager.getWorkAreaForMonitor(monitor);
-        let hscale = this.get_parent().allocation.get_width() / workArea.width;
-        let vscale = this.get_parent().allocation.get_height() / workArea.height;
-
-        let frameRect = this._window.get_frame_rect();
-        this.set_size(
-            Math.round(Math.min(frameRect.width, workArea.width) * hscale),
-            Math.round(Math.min(frameRect.height, workArea.height) * vscale));
-        this.set_position(
-            Math.round(frameRect.x * hscale),
-            Math.round(frameRect.y * vscale));
+    vfunc_get_preferred_height() {
+        return [0, 0];
+    }
+
+    vfunc_allocate(container, box) {
+        const monitor = Main.layoutManager.findIndexForActor(container);
+        const workArea = Main.layoutManager.getWorkAreaForMonitor(monitor);
+        const hscale = box.get_width() / workArea.width;
+        const vscale = box.get_height() / workArea.height;
+
+        for (const child of container) {
+            const childBox = new Clutter.ActorBox();
+            const frameRect = child.metaWindow.get_frame_rect();
+            childBox.set_size(
+                Math.round(Math.min(frameRect.width, workArea.width) * hscale),
+                Math.round(Math.min(frameRect.height, workArea.height) * vscale));
+            childBox.set_origin(
+                Math.round((frameRect.x - workArea.x) * hscale),
+                Math.round((frameRect.y - workArea.y)  * vscale));
+            child.allocate(childBox);
+        }
     }
 });
 
@@ -103,7 +102,7 @@ class WorkspaceThumbnail extends St.Button {
         super._init({
             style_class: 'workspace',
             child: new Clutter.Actor({
-                layout_manager: new Clutter.BinLayout(),
+                layout_manager: new WorkspaceLayout(),
                 clip_to_allocation: true,
             }),
         });
@@ -134,16 +133,15 @@ class WorkspaceThumbnail extends St.Button {
     }
 
     acceptDrop(source) {
-        if (!source.realWindow)
+        if (!source.metaWindow)
             return false;
 
-        let window = source.realWindow.get_meta_window();
-        this._moveWindow(window);
+        this._moveWindow(source.metaWindow);
         return true;
     }
 
     handleDragOver(source) {
-        if (source.realWindow)
+        if (source.metaWindow)
             return DND.DragMotionResult.MOVE_DROP;
         else
             return DND.DragMotionResult.CONTINUE;
diff --git a/extensions/windowsNavigator/extension.js b/extensions/windowsNavigator/extension.js
index 088cd3f..e4513d8 100644
--- a/extensions/windowsNavigator/extension.js
+++ b/extensions/windowsNavigator/extension.js
@@ -1,45 +1,12 @@
 /* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
 /* exported init */
-const { Clutter, GObject, St } = imports.gi;
+const { Clutter, Graphene, GObject, St } = imports.gi;
 
 const Main = imports.ui.main;
 const Workspace = imports.ui.workspace;
 const WorkspacesView = imports.ui.workspacesView;
 
-class MyWindowOverlay extends Workspace.WindowOverlay {
-    constructor(windowClone, parentActor) {
-        super(windowClone, parentActor);
-
-        this._id = null;
-        this._text = new St.Label({
-            style_class: 'extension-windowsNavigator-window-tooltip',
-            visible: false,
-        });
-        parentActor.add_actor(this._text);
-    }
-
-    showTooltip() {
-        this._parentActor.set_child_below_sibling(this._text, null);
-        this._text.show();
-        this._text.text = (this._windowClone.slotId + 1).toString();
-    }
-
-    hideTooltip() {
-        if (this._text && this._text.visible)
-            this._text.hide();
-    }
-
-    relayout(animate) {
-        super.relayout(animate);
-
-        let [cloneX, cloneY, cloneWidth_, cloneHeight_] = this._windowClone.slot;
-
-        let textX = cloneX - 2;
-        let textY = cloneY - 2;
-        this._text.set_position(Math.floor(textX) + 5, Math.floor(textY) + 5);
-        this._parentActor.set_child_below_sibling(this._text, null);
-    }
-}
+const WINDOW_SLOT = 4;
 
 var MyWorkspace = GObject.registerClass(
 class MyWorkspace extends Workspace.Workspace {
@@ -61,57 +28,89 @@ class MyWorkspace extends Workspace.Workspace {
         }
     }
 
+    vfunc_allocate(box) {
+        super.vfunc_allocate(box);
+
+        if (this._tip)
+            this._tip.allocate_preferred_size(0, 0);
+    }
+
     showTooltip() {
-        if (!this._tip || !this._actualGeometry)
+        if (!this._tip)
             return;
         this._tip.text = (this.metaWorkspace.index() + 1).toString();
-
-        // Hand code this instead of using _getSpacingAndPadding
-        // because that fails on empty workspaces
-        let node = this.get_theme_node();
-        let padding = {
-            left: node.get_padding(St.Side.LEFT),
-            top: node.get_padding(St.Side.TOP),
-            bottom: node.get_padding(St.Side.BOTTOM),
-            right: node.get_padding(St.Side.RIGHT),
-        };
-
-        let area = Workspace.padArea(this._actualGeometry, padding);
-        this._tip.x = area.x;
-        this._tip.y = area.y;
         this._tip.show();
         this.set_child_below_sibling(this._tip, null);
     }
 
     hideTooltip() {
-        if (!this._tip)
-            return;
-        if (!this._tip.get_parent())
-            return;
-        this._tip.hide();
+        if (this._tip)
+            this._tip.hide();
     }
 
     getWindowWithTooltip(id) {
-        for (let i = 0; i < this._windows.length; i++) {
-            if (this._windows[i].slotId + 1 === id)
-                return this._windows[i].metaWindow;
-        }
-        return null;
+        const slot = this.layout_manager._windowSlots[id - 1];
+        return slot ? slot[WINDOW_SLOT].metaWindow : null;
     }
 
     showWindowsTooltips() {
-        for (let i in this._windowOverlays) {
-            if (this._windowOverlays[i])
-                this._windowOverlays[i].showTooltip();
+        for (let i = 0; i < this.layout_manager._windowSlots.length; i++) {
+            if (this.layout_manager._windowSlots[i])
+                this.layout_manager._windowSlots[i][WINDOW_SLOT].showTooltip(`${i + 1}`);
         }
     }
 
     hideWindowsTooltips() {
-        for (let i in this._windowOverlays) {
-            if (this._windowOverlays[i])
-                this._windowOverlays[i].hideTooltip();
+        for (let i in this.layout_manager._windowSlots) {
+            if (this.layout_manager._windowSlots[i])
+                this.layout_manager._windowSlots[i][WINDOW_SLOT].hideTooltip();
         }
     }
+
+    // overriding _addWindowClone to apply the tooltip patch on the cloned
+    // windowPreview
+    _addWindowClone(metaWindow) {
+        const clone = super._addWindowClone(metaWindow);
+
+        // appling the tooltip patch
+        (function patchPreview() {
+            this._text = new St.Label({
+                style_class: 'extension-windowsNavigator-window-tooltip',
+                visible: false,
+            });
+
+            this._text.add_constraint(new Clutter.BindConstraint({
+                source: this._borderCenter,
+                coordinate: Clutter.BindCoordinate.POSITION,
+            }));
+            this._text.add_constraint(new Clutter.AlignConstraint({
+                source: this._borderCenter,
+                align_axis: Clutter.AlignAxis.X_AXIS,
+                pivot_point: new Graphene.Point({ x: 0.5, y: -1 }),
+                factor: this._closeButtonSide === St.Side.LEFT ? 1 : 0,
+            }));
+            this._text.add_constraint(new Clutter.AlignConstraint({
+                source: this._borderCenter,
+                align_axis: Clutter.AlignAxis.Y_AXIS,
+                pivot_point: new Graphene.Point({ x: -1, y: 0.5 }),
+                factor: 0,
+            }));
+
+            this.add_child(this._text);
+        }).call(clone);
+
+        clone.showTooltip = function (text) {
+            this._text.set({ text });
+            this._text.show();
+        };
+
+        clone.hideTooltip = function () {
+            if (this._text && this._text.visible)
+                this._text.hide();
+        };
+
+        return clone;
+    }
 });
 
 var MyWorkspacesView = GObject.registerClass(
@@ -244,19 +243,16 @@ class MyWorkspacesView extends WorkspacesView.WorkspacesView {
 
 class Extension {
     constructor() {
-        this._origWindowOverlay = Workspace.WindowOverlay;
         this._origWorkspace = Workspace.Workspace;
         this._origWorkspacesView = WorkspacesView.WorkspacesView;
     }
 
     enable() {
-        Workspace.WindowOverlay = MyWindowOverlay;
         Workspace.Workspace = MyWorkspace;
         WorkspacesView.WorkspacesView = MyWorkspacesView;
     }
 
     disable() {
-        Workspace.WindowOverlay = this._origWindowOverlay;
         Workspace.Workspace = this._origWorkspace;
         WorkspacesView.WorkspacesView = this._origWorkspacesView;
     }
diff --git a/extensions/workspace-indicator/extension.js b/extensions/workspace-indicator/extension.js
index 6d13acf..76b35df 100644
--- a/extensions/workspace-indicator/extension.js
+++ b/extensions/workspace-indicator/extension.js
@@ -30,27 +30,14 @@ class WindowPreview extends St.Button {
         this.connect('destroy', this._onDestroy.bind(this));
 
         this._sizeChangedId = this._window.connect('size-changed',
-            this._relayout.bind(this));
+            () => this.queue_relayout());
         this._positionChangedId = this._window.connect('position-changed',
-            this._relayout.bind(this));
-        this._minimizedChangedId = this._window.connect('notify::minimized',
-            this._relayout.bind(this));
-        this._monitorEnteredId = global.display.connect('window-entered-monitor',
-            this._relayout.bind(this));
-        this._monitorLeftId = global.display.connect('window-left-monitor',
-            this._relayout.bind(this));
-
-        // Do initial layout when we get a parent
-        let id = this.connect('parent-set', () => {
-            this.disconnect(id);
-            if (!this.get_parent())
-                return;
-            this._laterId = Meta.later_add(Meta.LaterType.BEFORE_REDRAW, () => {
-                this._laterId = 0;
-                this._relayout();
-                return false;
+            () => {
+                this._updateVisible();
+                this.queue_relayout();
             });
-        });
+        this._minimizedChangedId = this._window.connect('notify::minimized',
+            this._updateVisible.bind(this));
 
         this._focusChangedId = global.display.connect('notify::focus-window',
             this._onFocusChanged.bind(this));
@@ -58,19 +45,15 @@ class WindowPreview extends St.Button {
     }
 
     // needed for DND
-    get realWindow() {
-        return this._window.get_compositor_private();
+    get metaWindow() {
+        return this._window;
     }
 
     _onDestroy() {
         this._window.disconnect(this._sizeChangedId);
         this._window.disconnect(this._positionChangedId);
         this._window.disconnect(this._minimizedChangedId);
-        global.display.disconnect(this._monitorEnteredId);
-        global.display.disconnect(this._monitorLeftId);
         global.display.disconnect(this._focusChangedId);
-        if (this._laterId)
-            Meta.later_remove(this._laterId);
     }
 
     _onFocusChanged() {
@@ -80,26 +63,42 @@ class WindowPreview extends St.Button {
             this.remove_style_class_name('active');
     }
 
-    _relayout() {
-        let monitor = Main.layoutManager.findIndexForActor(this);
-        this.visible = monitor === this._window.get_monitor() &&
+    _updateVisible() {
+        const monitor = Main.layoutManager.findIndexForActor(this);
+        const workArea = Main.layoutManager.getWorkAreaForMonitor(monitor);
+        this.visible = this._window.get_frame_rect().overlap(workArea) &&
             this._window.window_type !== Meta.WindowType.DESKTOP &&
             this._window.showing_on_its_workspace();
+    }
+});
 
-        if (!this.visible)
-            return;
+let WorkspaceLayout = GObject.registerClass(
+class WorkspaceLayout extends Clutter.LayoutManager {
+    vfunc_get_preferred_width() {
+        return [0, 0];
+    }
 
-        let workArea = Main.layoutManager.getWorkAreaForMonitor(monitor);
-        let hscale = this.get_parent().allocation.get_width() / workArea.width;
-        let vscale = this.get_parent().allocation.get_height() / workArea.height;
-
-        let frameRect = this._window.get_frame_rect();
-        this.set_size(
-            Math.round(Math.min(frameRect.width, workArea.width) * hscale),
-            Math.round(Math.min(frameRect.height, workArea.height) * vscale));
-        this.set_position(
-            Math.round(frameRect.x * hscale),
-            Math.round(frameRect.y * vscale));
+    vfunc_get_preferred_height() {
+        return [0, 0];
+    }
+
+    vfunc_allocate(container, box) {
+        const monitor = Main.layoutManager.findIndexForActor(container);
+        const workArea = Main.layoutManager.getWorkAreaForMonitor(monitor);
+        const hscale = box.get_width() / workArea.width;
+        const vscale = box.get_height() / workArea.height;
+
+        for (const child of container) {
+            const childBox = new Clutter.ActorBox();
+            const frameRect = child.metaWindow.get_frame_rect();
+            childBox.set_size(
+                Math.round(Math.min(frameRect.width, workArea.width) * hscale),
+                Math.round(Math.min(frameRect.height, workArea.height) * vscale));
+            childBox.set_origin(
+                Math.round((frameRect.x - workArea.x) * hscale),
+                Math.round((frameRect.y - workArea.y) * vscale));
+            child.allocate(childBox);
+        }
     }
 });
 
@@ -109,7 +108,7 @@ class WorkspaceThumbnail extends St.Button {
         super._init({
             style_class: 'workspace',
             child: new Clutter.Actor({
-                layout_manager: new Clutter.BinLayout(),
+                layout_manager: new WorkspaceLayout(),
                 clip_to_allocation: true,
             }),
         });
@@ -140,16 +139,15 @@ class WorkspaceThumbnail extends St.Button {
     }
 
     acceptDrop(source) {
-        if (!source.realWindow)
+        if (!source.metaWindow)
             return false;
 
-        let window = source.realWindow.get_meta_window();
-        this._moveWindow(window);
+        this._moveWindow(source.metaWindow);
         return true;
     }
 
     handleDragOver(source) {
-        if (source.realWindow)
+        if (source.metaWindow)
             return DND.DragMotionResult.MOVE_DROP;
         else
             return DND.DragMotionResult.CONTINUE;
diff --git a/meson.build b/meson.build
index f07b82e..2e26532 100644
--- a/meson.build
+++ b/meson.build
@@ -1,5 +1,5 @@
 project('gnome-shell-extensions',
-  version: '3.38.1',
+  version: '3.38.2',
   meson_version: '>= 0.44.0',
   license: 'GPL2+'
 )