Skip to content

Commit

Permalink
Fix drag and drop in workspace thumbnails of overview
Browse files Browse the repository at this point in the history
This was originally implemented by @mainland.

The ThumbnailsBox base class only uses the x coordinate to test whether a point
is in a workspace. This is not sufficient when we may have multiple rows of
thumbnails.

The new _withinWorkspace function also uses the y coordinate. This requires
overriding handleDragOver as well so that it passes both the x and y coordinates
to _withinWorkspace.

References mainland@62be78e8
References #177
  • Loading branch information
mzur committed Nov 4, 2023
1 parent 3351591 commit cb29bcc
Showing 1 changed file with 83 additions and 0 deletions.
83 changes: 83 additions & 0 deletions wsmatrix@martin.zurowietz.de/overview/thumbnailsBox.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,11 @@ import {
ThumbnailState,
ThumbnailsBox as GThumbnailsBox
} from 'resource:///org/gnome/shell/ui/workspaceThumbnail.js';
import {DragMotionResult} from 'resource:///org/gnome/shell/ui/dnd.js';
import * as Main from 'resource:///org/gnome/shell/ui/main.js';

// Can't import this from workspaceThumbnail.js.
const WORKSPACE_CUT_SIZE = 10;

const addThumbnails = function (start, count) {
let workspaceManager = global.workspace_manager;
Expand Down Expand Up @@ -290,6 +294,73 @@ const vfunc_allocate = function(box) {
this._indicator.allocate(childBox);
}

const _withinWorkspace = function (x, y, index, rtl) {
const length = this._thumbnails.length;
const workspace = this._thumbnails[index];

let workspaceX1 = workspace.x + WORKSPACE_CUT_SIZE;
let workspaceX2 = workspace.x + workspace.width - WORKSPACE_CUT_SIZE;

if (index === length - 1) {
if (rtl)
workspaceX1 -= WORKSPACE_CUT_SIZE;
else
workspaceX2 += WORKSPACE_CUT_SIZE;
}

let workspaceY1 = workspace.y;
let workspaceY2 = workspace.y + workspace.height;

return x > workspaceX1 && x <= workspaceX2 && y > workspaceY1 && y <= workspaceY2;
}

// Draggable target interface
const handleDragOver = function(source, actor, x, y, time) {
if (!source.metaWindow &&
(!source.app || !source.app.can_open_new_window()) &&
(source.app || !source.shellWorkspaceLaunch) &&
source != Main.xdndHandler)
return DragMotionResult.CONTINUE;

const rtl = Clutter.get_default_text_direction() === Clutter.TextDirection.RTL;
let canCreateWorkspaces = Meta.prefs_get_dynamic_workspaces();
let spacing = this.get_theme_node().get_length('spacing');

this._dropWorkspace = -1;
let placeholderPos = -1;
let length = this._thumbnails.length;
for (let i = 0; i < length; i++) {
const index = rtl ? length - i - 1 : i;

if (canCreateWorkspaces && source !== Main.xdndHandler) {
const [targetStart, targetEnd] =
this._getPlaceholderTarget(index, spacing, rtl);

if (x > targetStart && x <= targetEnd) {
placeholderPos = index;
break;
}
}

if (this._withinWorkspace(x, y, index, rtl)) {
this._dropWorkspace = index;
break;
}
}

if (this._dropPlaceholderPos != placeholderPos) {
this._dropPlaceholderPos = placeholderPos;
this.queue_relayout();
}

if (this._dropWorkspace != -1)
return this._thumbnails[this._dropWorkspace].handleDragOverInternal(source, actor, time);
else if (this._dropPlaceholderPos != -1)
return source.metaWindow ? DragMotionResult.MOVE_DROP : DragMotionResult.COPY_DROP;
else
return DragMotionResult.CONTINUE;
}

export default class ThumbnailsBox extends Override {
enable() {
const subject = GThumbnailsBox.prototype;
Expand All @@ -316,5 +387,17 @@ export default class ThumbnailsBox extends Override {
return vfunc_allocate.call(this, ...arguments);
};
});

this._im.overrideMethod(subject, '_withinWorkspace', (original) => {
return function () {
return _withinWorkspace.call(this, ...arguments);
};
});

this._im.overrideMethod(subject, 'handleDragOver', (original) => {
return function () {
return handleDragOver.call(this, ...arguments);
};
});
}
}

0 comments on commit cb29bcc

Please sign in to comment.