Commit c9d875d6 authored by Xiaoguang Wang's avatar Xiaoguang Wang Committed by sunwxg
Browse files

window-list: Add ability to drag window button

Drag button and move button to new position.

Fixes GNOME/gnome-shell-extensions#4
parent 062f5e19
Pipeline #1677 passed with stage
in 2 minutes and 48 seconds
......@@ -5,6 +5,7 @@ const Gtk = imports.gi.Gtk;
const Meta = imports.gi.Meta;
const Shell = imports.gi.Shell;
const St = imports.gi.St;
const Signals = imports.signals;
const DND = imports.ui.dnd;
const Main = imports.ui.main;
......@@ -358,6 +359,38 @@ class WindowButton extends BaseButton {
global.display.connect('notify::focus-window',
this._updateStyle.bind(this));
this._updateStyle();
this._draggable = DND.makeDraggable(this.actor);
this._draggable.connect('drag-begin', this._onDragBegin.bind(this));
this._draggable.connect('drag-cancelled', this._onDragCancelled.bind(this));
this._draggable.connect('drag-end', this._onDragEnd.bind(this));
}
_onDragBegin() {
this.actor.opacity = 100;
this.emit('drag-begin');
}
_onDragCancelled() {
this.actor.opacity = 255;
this.emit('drag-cancelled');
}
_onDragEnd() {
this.actor.opacity = 255;
this.emit('drag-end');
}
getDragActor() {
let dragButton = new WindowButton(this.metaWindow);
dragButton.actor.set_width(this.actor.get_width());
dragButton.actor.set_height(this.actor.get_height());
return dragButton.actor;
}
getDragActorSource() {
return this.actor;
}
_onClicked(actor, button) {
......@@ -405,6 +438,7 @@ class WindowButton extends BaseButton {
this._contextMenu.destroy();
}
};
Signals.addSignalMethods(WindowButton.prototype);
class AppContextMenu extends PopupMenu.PopupMenu {
......@@ -868,25 +902,16 @@ class WindowList {
this._updateKeyboardAnchor();
});
this._dragBeginId =
Main.xdndHandler.connect('drag-begin',
this._onDragBegin.bind(this));
this._dragEndId =
Main.xdndHandler.connect('drag-end',
this._onDragEnd.bind(this));
this._dragMonitor = {
dragMotion: this._onDragMotion.bind(this)
};
this._dndTimeoutId = 0;
this._dndWindow = null;
this._settings = Convenience.getSettings();
this._groupingModeChangedId =
this._settings.connect('changed::grouping-mode',
this._groupingModeChanged.bind(this));
this._grouped = undefined;
this._groupingModeChanged();
this.actor._delegate = this;
this.dragButton= null;
this._dragMonitor = { dragMotion: this._onDragMotion.bind(this) };
}
_getDynamicWorkspacesSettings() {
......@@ -1065,6 +1090,10 @@ class WindowList {
true, true, true,
Clutter.BoxAlignment.START,
Clutter.BoxAlignment.START);
button.connect('drag-begin', this._onDragBegin.bind(this));
button.connect('drag-cancelled', this._onDragCancelled.bind(this));
button.connect('drag-end', this._onDragEnd.bind(this));
}
_onWindowRemoved(ws, win) {
......@@ -1121,53 +1150,60 @@ class WindowList {
DND.addDragMonitor(this._dragMonitor);
}
_onDragCancelled() {
DND.removeDragMonitor(this._dragMonitor);
this.dragButton = null;
}
_onDragEnd() {
DND.removeDragMonitor(this._dragMonitor);
this._removeActivateTimeout();
this.dragButton = null;
}
_onDragMotion(dragEvent) {
if (Main.overview.visible ||
!this.actor.contains(dragEvent.targetActor)) {
this._removeActivateTimeout();
return DND.DragMotionResult.CONTINUE;
}
return DND.DragMotionResult.CONTINUE;
}
let hoveredWindow = null;
if (dragEvent.targetActor._delegate)
hoveredWindow = dragEvent.targetActor._delegate.metaWindow;
handleDragOver(source, actor, x, y, time) {
this._moveDragButton(source, actor, x, y);
return DND.DragMotionResult.COPY_DROP;
}
if (!hoveredWindow ||
this._dndWindow == hoveredWindow)
return DND.DragMotionResult.CONTINUE;
acceptDrop(source, actor, x, y, time) {
this._moveDragButton(source, actor, x, y);
return true;
}
this._removeActivateTimeout();
_moveDragButton(source, actor, x ,y) {
let numChildren = this._windowList.get_n_children();
let position;
if (numChildren == 0) {
position = 0;
} else {
let firstChild = this._windowList.get_first_child();
let buttonWidth = firstChild.width;
position = Math.floor((x - firstChild.x) / buttonWidth);
}
this._dndWindow = hoveredWindow;
this._dndTimeoutId = GLib.timeout_add(GLib.PRIORITY_DEFAULT,
DND_ACTIVATE_TIMEOUT,
this._activateWindow.bind(this));
if (position >= this._windowList.get_n_children())
position = this._windowList.get_n_children() - 1;
return DND.DragMotionResult.CONTINUE;
}
if (this.dragButton == null)
this.dragButton = this._findDragButton(source);
_removeActivateTimeout() {
if (this._dndTimeoutId)
GLib.source_remove (this._dndTimeoutId);
this._dndTimeoutId = 0;
this._dndWindow = null;
this._windowList.set_child_at_index(this.dragButton, position);
}
_activateWindow() {
let [x, y] = global.get_pointer();
let pickedActor = global.stage.get_actor_at_pos(Clutter.PickMode.ALL, x, y);
if (this._dndWindow && this.actor.contains(pickedActor))
this._dndWindow.activate(global.get_current_time());
this._dndWindow = null;
this._dndTimeoutId = 0;
return false;
_findDragButton(source) {
let dragButton = null;
let children = this._windowList.get_children();
for (let i = 0; i < children.length; i++) {
if (children[i]._delegate.metaWindow == source.metaWindow) {
dragButton = children[i];
break;
}
}
return dragButton;
}
_onDestroy() {
......@@ -1199,9 +1235,6 @@ class WindowList {
global.screen.disconnect(this._fullscreenChangedId);
Main.xdndHandler.disconnect(this._dragBeginId);
Main.xdndHandler.disconnect(this._dragEndId);
this._settings.disconnect(this._groupingModeChangedId);
let windows = global.get_window_actors();
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment