quick tiling: find target output by direction
This commit is contained in:
parent
67c558286f
commit
0053c782a1
5 changed files with 43 additions and 49 deletions
|
@ -14,6 +14,7 @@
|
|||
#include "decorations/decorationbridge.h"
|
||||
#include "decorations/settings.h"
|
||||
#include "scripting/scripting.h"
|
||||
#include "utils/common.h"
|
||||
#include "wayland_server.h"
|
||||
#include "window.h"
|
||||
#include "workspace.h"
|
||||
|
@ -130,9 +131,9 @@ void QuickTilingTest::testQuickTiling_data()
|
|||
#define FLAG(name) QuickTileMode(QuickTileFlag::name)
|
||||
|
||||
QTest::newRow("left") << FLAG(Left) << QRectF(0, 0, 640, 1024) << QRectF(1280, 0, 640, 1024) << FLAG(Right);
|
||||
QTest::newRow("top") << FLAG(Top) << QRectF(0, 0, 1280, 512) << QRectF(1280, 0, 1280, 512) << FLAG(Top);
|
||||
QTest::newRow("top") << FLAG(Top) << QRectF(0, 0, 1280, 512) << QRectF(1280, 0, 1280, 512) << QuickTileMode();
|
||||
QTest::newRow("right") << FLAG(Right) << QRectF(640, 0, 640, 1024) << QRectF(1920, 0, 640, 1024) << QuickTileMode();
|
||||
QTest::newRow("bottom") << FLAG(Bottom) << QRectF(0, 512, 1280, 512) << QRectF(1280, 512, 1280, 512) << FLAG(Bottom);
|
||||
QTest::newRow("bottom") << FLAG(Bottom) << QRectF(0, 512, 1280, 512) << QRectF(1280, 512, 1280, 512) << QuickTileMode();
|
||||
|
||||
QTest::newRow("top left") << (FLAG(Left) | FLAG(Top)) << QRectF(0, 0, 640, 512) << QRectF(1280, 0, 640, 512) << (FLAG(Right) | FLAG(Top));
|
||||
QTest::newRow("top right") << (FLAG(Right) | FLAG(Top)) << QRectF(640, 0, 640, 512) << QRectF(1920, 0, 640, 512) << QuickTileMode();
|
||||
|
@ -535,9 +536,9 @@ void QuickTilingTest::testX11QuickTiling_data()
|
|||
#define FLAG(name) QuickTileMode(QuickTileFlag::name)
|
||||
|
||||
QTest::newRow("left") << FLAG(Left) << QRectF(0, 0, 640, 1024) << 0 << QuickTileMode();
|
||||
QTest::newRow("top") << FLAG(Top) << QRectF(0, 0, 1280, 512) << 1 << FLAG(Top);
|
||||
QTest::newRow("top") << FLAG(Top) << QRectF(0, 0, 1280, 512) << 0 << QuickTileMode();
|
||||
QTest::newRow("right") << FLAG(Right) << QRectF(640, 0, 640, 1024) << 1 << FLAG(Left);
|
||||
QTest::newRow("bottom") << FLAG(Bottom) << QRectF(0, 512, 1280, 512) << 1 << FLAG(Bottom);
|
||||
QTest::newRow("bottom") << FLAG(Bottom) << QRectF(0, 512, 1280, 512) << 0 << QuickTileMode();
|
||||
|
||||
QTest::newRow("top left") << (FLAG(Left) | FLAG(Top)) << QRectF(0, 0, 640, 512) << 0 << QuickTileMode();
|
||||
QTest::newRow("top right") << (FLAG(Right) | FLAG(Top)) << QRectF(640, 0, 640, 512) << 1 << (FLAG(Left) | FLAG(Top));
|
||||
|
@ -587,6 +588,7 @@ void QuickTilingTest::testX11QuickTiling()
|
|||
QCOMPARE(quickTileChangedSpy.count(), 1);
|
||||
|
||||
// quick tile to same edge again should also act like send to screen
|
||||
// if screen is on the same edge
|
||||
const auto outputs = workspace()->outputs();
|
||||
QCOMPARE(window->output(), outputs[0]);
|
||||
window->setQuickTileMode(mode, true);
|
||||
|
|
|
@ -1353,42 +1353,42 @@ void Workspace::slotSwitchToScreen(Output *output)
|
|||
void Workspace::slotSwitchToLeftScreen()
|
||||
{
|
||||
if (!screenSwitchImpossible()) {
|
||||
switchToOutput(outputFrom(activeOutput(), Direction::DirectionWest, true));
|
||||
switchToOutput(findOutput(activeOutput(), Direction::DirectionWest, true));
|
||||
}
|
||||
}
|
||||
|
||||
void Workspace::slotSwitchToRightScreen()
|
||||
{
|
||||
if (!screenSwitchImpossible()) {
|
||||
switchToOutput(outputFrom(activeOutput(), Direction::DirectionEast, true));
|
||||
switchToOutput(findOutput(activeOutput(), Direction::DirectionEast, true));
|
||||
}
|
||||
}
|
||||
|
||||
void Workspace::slotSwitchToAboveScreen()
|
||||
{
|
||||
if (!screenSwitchImpossible()) {
|
||||
switchToOutput(outputFrom(activeOutput(), Direction::DirectionNorth, true));
|
||||
switchToOutput(findOutput(activeOutput(), Direction::DirectionNorth, true));
|
||||
}
|
||||
}
|
||||
|
||||
void Workspace::slotSwitchToBelowScreen()
|
||||
{
|
||||
if (!screenSwitchImpossible()) {
|
||||
switchToOutput(outputFrom(activeOutput(), Direction::DirectionSouth, true));
|
||||
switchToOutput(findOutput(activeOutput(), Direction::DirectionSouth, true));
|
||||
}
|
||||
}
|
||||
|
||||
void Workspace::slotSwitchToPrevScreen()
|
||||
{
|
||||
if (!screenSwitchImpossible()) {
|
||||
switchToOutput(outputFrom(activeOutput(), Direction::DirectionPrev, true));
|
||||
switchToOutput(findOutput(activeOutput(), Direction::DirectionPrev, true));
|
||||
}
|
||||
}
|
||||
|
||||
void Workspace::slotSwitchToNextScreen()
|
||||
{
|
||||
if (!screenSwitchImpossible()) {
|
||||
switchToOutput(outputFrom(activeOutput(), Direction::DirectionNext, true));
|
||||
switchToOutput(findOutput(activeOutput(), Direction::DirectionNext, true));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1402,42 +1402,42 @@ void Workspace::slotWindowToScreen(Output *output)
|
|||
void Workspace::slotWindowToLeftScreen()
|
||||
{
|
||||
if (USABLE_ACTIVE_WINDOW) {
|
||||
sendWindowToOutput(m_activeWindow, outputFrom(m_activeWindow->output(), Direction::DirectionWest, true));
|
||||
sendWindowToOutput(m_activeWindow, findOutput(m_activeWindow->output(), Direction::DirectionWest, true));
|
||||
}
|
||||
}
|
||||
|
||||
void Workspace::slotWindowToRightScreen()
|
||||
{
|
||||
if (USABLE_ACTIVE_WINDOW) {
|
||||
sendWindowToOutput(m_activeWindow, outputFrom(m_activeWindow->output(), Direction::DirectionEast, true));
|
||||
sendWindowToOutput(m_activeWindow, findOutput(m_activeWindow->output(), Direction::DirectionEast, true));
|
||||
}
|
||||
}
|
||||
|
||||
void Workspace::slotWindowToAboveScreen()
|
||||
{
|
||||
if (USABLE_ACTIVE_WINDOW) {
|
||||
sendWindowToOutput(m_activeWindow, outputFrom(m_activeWindow->output(), Direction::DirectionNorth, true));
|
||||
sendWindowToOutput(m_activeWindow, findOutput(m_activeWindow->output(), Direction::DirectionNorth, true));
|
||||
}
|
||||
}
|
||||
|
||||
void Workspace::slotWindowToBelowScreen()
|
||||
{
|
||||
if (USABLE_ACTIVE_WINDOW) {
|
||||
sendWindowToOutput(m_activeWindow, outputFrom(m_activeWindow->output(), Direction::DirectionSouth, true));
|
||||
sendWindowToOutput(m_activeWindow, findOutput(m_activeWindow->output(), Direction::DirectionSouth, true));
|
||||
}
|
||||
}
|
||||
|
||||
void Workspace::slotWindowToPrevScreen()
|
||||
{
|
||||
if (USABLE_ACTIVE_WINDOW) {
|
||||
sendWindowToOutput(m_activeWindow, outputFrom(m_activeWindow->output(), Direction::DirectionPrev, true));
|
||||
sendWindowToOutput(m_activeWindow, findOutput(m_activeWindow->output(), Direction::DirectionPrev, true));
|
||||
}
|
||||
}
|
||||
|
||||
void Workspace::slotWindowToNextScreen()
|
||||
{
|
||||
if (USABLE_ACTIVE_WINDOW) {
|
||||
sendWindowToOutput(m_activeWindow, outputFrom(m_activeWindow->output(), Direction::DirectionNext, true));
|
||||
sendWindowToOutput(m_activeWindow, findOutput(m_activeWindow->output(), Direction::DirectionNext, true));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
|
||||
#include "core/output.h"
|
||||
#include "tiles/tilemanager.h"
|
||||
#include "utils/common.h"
|
||||
|
||||
#if KWIN_BUILD_ACTIVITIES
|
||||
#include "activities.h"
|
||||
|
@ -3860,49 +3861,40 @@ void Window::setQuickTileMode(QuickTileMode mode, bool keyboard)
|
|||
QPointF whichScreen = keyboard ? moveResizeGeometry().center() : Cursors::self()->mouse()->pos();
|
||||
if (mode != QuickTileMode(QuickTileFlag::None)) {
|
||||
// If trying to tile to the side that the window is already tiled to move the window to the next
|
||||
// screen if it exists, otherwise toggle the mode (set QuickTileFlag::None)
|
||||
// screen near the tile if it exists and swap the tile side, otherwise toggle the mode (set QuickTileFlag::None)
|
||||
if (quickTileMode() == mode) {
|
||||
const QList<Output *> outputs = workspace()->outputs();
|
||||
const Output *currentOutput = moveResizeOutput();
|
||||
const Output *nextOutput = currentOutput;
|
||||
|
||||
for (const Output *output : outputs) {
|
||||
if (output == currentOutput) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (output->geometry().bottom() <= currentOutput->geometry().top()
|
||||
|| output->geometry().top() >= currentOutput->geometry().bottom()) {
|
||||
continue; // not in horizontal line
|
||||
}
|
||||
|
||||
const int x = output->geometry().center().x();
|
||||
if ((mode & QuickTileFlag::Horizontal) == QuickTileMode(QuickTileFlag::Left)) {
|
||||
if (x >= currentOutput->geometry().center().x()
|
||||
|| (currentOutput != nextOutput && x <= nextOutput->geometry().center().x())) {
|
||||
continue; // not left of current or more left then found next
|
||||
}
|
||||
} else if ((mode & QuickTileFlag::Horizontal) == QuickTileMode(QuickTileFlag::Right)) {
|
||||
if (x <= currentOutput->geometry().center().x()
|
||||
|| (currentOutput != nextOutput && x >= nextOutput->geometry().center().x())) {
|
||||
continue; // not right of current or more right then found next
|
||||
}
|
||||
}
|
||||
|
||||
nextOutput = output;
|
||||
Output *currentOutput = moveResizeOutput();
|
||||
Output *nextOutput = currentOutput;
|
||||
Output *candidateOutput = currentOutput;
|
||||
if ((mode & QuickTileFlag::Horizontal) == QuickTileMode(QuickTileFlag::Left)) {
|
||||
candidateOutput = workspace()->findOutput(nextOutput, Workspace::DirectionWest);
|
||||
} else if ((mode & QuickTileFlag::Horizontal) == QuickTileMode(QuickTileFlag::Right)) {
|
||||
candidateOutput = workspace()->findOutput(nextOutput, Workspace::DirectionEast);
|
||||
}
|
||||
bool shiftHorizontal = candidateOutput != nextOutput;
|
||||
nextOutput = candidateOutput;
|
||||
if ((mode & QuickTileFlag::Vertical) == QuickTileMode(QuickTileFlag::Top)) {
|
||||
candidateOutput = workspace()->findOutput(nextOutput, Workspace::DirectionNorth);
|
||||
} else if ((mode & QuickTileFlag::Vertical) == QuickTileMode(QuickTileFlag::Bottom)) {
|
||||
candidateOutput = workspace()->findOutput(nextOutput, Workspace::DirectionSouth);
|
||||
}
|
||||
bool shiftVertical = candidateOutput != nextOutput;
|
||||
nextOutput = candidateOutput;
|
||||
|
||||
if (nextOutput == currentOutput) {
|
||||
mode = QuickTileFlag::None; // No other screens, toggle tiling
|
||||
mode = QuickTileFlag::None; // No other screens in the tile direction, toggle tiling
|
||||
} else {
|
||||
// Move to other screen
|
||||
moveResize(geometryRestore().translated(nextOutput->geometry().topLeft() - currentOutput->geometry().topLeft()));
|
||||
whichScreen = nextOutput->geometry().center();
|
||||
|
||||
// Swap sides
|
||||
if (mode & QuickTileFlag::Horizontal) {
|
||||
if (shiftHorizontal) {
|
||||
mode = (~mode & QuickTileFlag::Horizontal) | (mode & QuickTileFlag::Vertical);
|
||||
}
|
||||
if (shiftVertical) {
|
||||
mode = (~mode & QuickTileFlag::Vertical) | (mode & QuickTileFlag::Horizontal);
|
||||
}
|
||||
}
|
||||
} else if (quickTileMode() == QuickTileMode(QuickTileFlag::None)) {
|
||||
// Not coming out of an existing tile, not shifting monitors, we're setting a brand new tile.
|
||||
|
|
|
@ -1408,7 +1408,7 @@ Output *Workspace::outputAt(const QPointF &pos) const
|
|||
return bestOutput;
|
||||
}
|
||||
|
||||
Output *Workspace::outputFrom(Output *reference, Direction direction, bool wrapAround) const
|
||||
Output *Workspace::findOutput(Output *reference, Direction direction, bool wrapAround) const
|
||||
{
|
||||
QList<Output *> relevantOutputs;
|
||||
std::copy_if(m_outputs.begin(), m_outputs.end(), std::back_inserter(relevantOutputs), [reference, direction](Output *output) {
|
||||
|
|
|
@ -363,7 +363,7 @@ public:
|
|||
DirectionPrev,
|
||||
DirectionNext
|
||||
};
|
||||
Output *outputFrom(Output *reference, Direction direction, bool wrapAround = false) const;
|
||||
Output *findOutput(Output *reference, Direction direction, bool wrapAround = false) const;
|
||||
void switchToOutput(Output *output);
|
||||
|
||||
QList<Output *> outputs() const;
|
||||
|
|
Loading…
Reference in a new issue