Open luisfpg opened 7 years ago
I know, I know, I want this feature, too. I'll look into it, thanks for suggestion :).
That would certainly be a nice add :)
Or add a "Move" button/menu entry, like what is available in the taskbar's right click menu > More Actions.
I would love this so gosh darn much! Any updates, @kotelnik?
Any updates? 😋
The taskmanager widget can ask to "move the selected window".
I've managed to get this sorta working with:
MouseArea {
onClicked: {
tasksModel.requestMove(tasksModel.activeTask)
}
}
Video: https://streamable.com/vziac
However if I try triggering the requestMove
in the middle of a drag, it foobars when the mouse is released. Mouse clicks are no longer registered.
I need to hit the global shortcut for KRunner
to get input to work. I can also press Esc
to fix it, but the window moves back to it's original location (which is a hint that it's KWin's state that's messed up instead of the plasmashell widget).
MouseArea {
Item {
id: dragTarget
anchors.fill: parent
}
drag.target: dragTarget
drag.onActiveChanged: console.log('drag.onActiveChanged', drag.active)
onContainsMouseChanged: {
console.log('onContainsMouseChanged', containsMouse)
if (!containsMouse) {
if (drag.active) {
console.log('!containsMouse && drag.active')
console.log('requestMove', tasksModel.activeTask)
tasksModel.requestMove(tasksModel.activeTask)
console.log('after tasksModel.requestMove')
}
}
}
}
Video: https://streamable.com/weraq
Should it be possible to trigger it during a drag without breaking, we also need to make requestMouse
not move the mouse to the center of the window.
The code for the X11 libtaskmanager is here:
https://github.com/KDE/plasma-workspace/blob/master/libtaskmanager/xwindowtasksmodel.cpp#L719
void XWindowTasksModel::requestMove(const QModelIndex &index)
{
if (!index.isValid() || index.model() != this || index.row() < 0 || index.row() >= d->windows.count()) {
return;
}
const WId window = d->windows.at(index.row());
const KWindowInfo *info = d->windowInfo(window);
bool onCurrent = info->isOnCurrentDesktop();
if (!onCurrent) {
KWindowSystem::setCurrentDesktop(info->desktop());
KWindowSystem::forceActiveWindow(window);
}
if (info->isMinimized()) {
KWindowSystem::unminimizeWindow(window);
}
const QRect &geom = info->geometry();
NETRootInfo ri(QX11Info::connection(), NET::WMMoveResize);
ri.moveResizeRequest(window, geom.center().x(), geom.center().y(), NET::Move);
}
Note the geom.center()
. We'll need to ship our own C++ function that triggers the move at the current mouse coordinates so the mouse doesn't jump to the center.
if (direction == NET::Move) {
// move cursor to the provided position to prevent the window jumping there on first movement
// the expectation is that the cursor is already at the provided position,
// thus it's more a safety measurement
Cursor::setPos(QPoint(x_root, y_root));
performMouseCommand(Options::MouseMove, QPoint(x_root, y_root));
case Options::MouseMove:
case Options::MouseUnrestrictedMove: {
if (!isMovableAcrossScreens())
break;
if (isMoveResize())
finishMoveResize(false);
setMoveResizePointerMode(PositionCenter);
setMoveResizePointerButtonDown(true);
setMoveOffset(QPoint(globalPos.x() - x(), globalPos.y() - y())); // map from global
setInvertedMoveOffset(rect().bottomRight() - moveOffset());
setUnrestrictedMoveResize((cmd == Options::MouseActivateRaiseAndUnrestrictedMove
|| cmd == Options::MouseUnrestrictedMove));
if (!startMoveResize())
setMoveResizePointerButtonDown(false);
updateCursor();
break;
}
Note:
onClicked
(aka mouse button is up) will:
requestMove
is calledEsc
the window resets to it's original positionAlt+Space
, it opens KRunner and you can type into it. Esc will close Krunner and cancel the drag
.onPressed
(aka mouse button is still down) will:
requestMove
is calledEsc
the window resets to it's original positionMeta
the Menu will appear, but you can't type anything or click it.Alt+Space
to open KRunner, while KRunner doesn't show, you will regain control and mouse clicks start working again. Eg: If you do Alt+Space
a second time, it will open KRunner.Wonderful work @Zren, thanks for your interest, code and time spent on this! I'll dive in right away.
I can reproduce the bug with the "Window Move" global shortcut, so I think this might be a KWin bug.
So according to the KWin maintainer, it seems we need to "ungrab" the mouse before calling tasksModel.requestMove(tasksModel.activeTask)
.
I recently found KDeclarative's EventGenerator class, but I can't seem to get any good results. It's still buggy.
import org.kde.kquickcontrolsaddons 2.0 // EventGenerator
MouseArea {
EventGenerator {
id: eventGenerator
}
onPressed: {
eventGenerator.sendGrabEvent(mouseArea, EventGenerator.UngrabMouse)
tasksModel.requestMove(tasksModel.activeTask)
}
}
Wasn't able to get it working with kdeclariative's MouseEventListener either.
Hi! I have the same problem. Some apps can be dragged from maximized status(firefox) but konsole, vscode ..... can`t dragged directorly.
This request is to be able to move the current window by dragging the applet. This is a nice complement for the option to hide the title bar for maximized windows. In such case there is no title bar to drag (and unmaximize) the window. Kwin has the option in the right click menu to move the window, so I assume it would be possible. Unity allows a similar behavior, where the top panel really feels like the "maximized window decoration". If you prefer this could be enabled with an option, and even the option could restrict to maximized windows only.