/* SPDX-License-Identifier: GPL-3.0-or-later */ #pragma once #include "effect/effect.h" #include #include #include #include namespace KWin { class EffectWindow; class LogicalOutput; class WindowGridEffect : public Effect { Q_OBJECT public: WindowGridEffect(); ~WindowGridEffect() override; void reconfigure(ReconfigureFlags flags) override; bool isActive() const override; bool paintScreen(const RenderTarget &renderTarget, const RenderViewport &viewport, int mask, const Region &deviceRegion, LogicalOutput *screen) override; void pointerMotion(PointerMotionEvent *event) override; void pointerButton(PointerButtonEvent *event) override; void grabbedKeyboardEvent(QKeyEvent *e) override; private: // Native: KWin is doing the normal title bar move. Grid: we own the pointer and // show the overlay. Moving: middle button held, window follows the cursor. enum class State { Idle, Native, Grid, Moving, }; struct Cell { int col = 0; int row = 0; }; void watchWindow(EffectWindow *w); void onMoveStarted(EffectWindow *w); void onMoveFinished(EffectWindow *w); void onMouseChanged(const QPointF &pos, const QPointF &oldpos, Qt::MouseButtons buttons, Qt::MouseButtons oldbuttons); void enterGrid(bool viaSpace); void finish(bool restoreGeometry); void updateArea(const QPointF &pos); Cell cellAt(const QPointF &pos) const; QRectF cellRect(Cell a, Cell b) const; void setSelecting(bool rightButton, bool space, const QPointF &pos); void applySelection(); void moveWithCursor(const QPointF &pos); State m_state = State::Idle; QPointer m_window; QMetaObject::Connection m_mouseConnection; bool m_keyboardGrabbed = false; QRectF m_originalGeometry; LogicalOutput *m_screen = nullptr; QRectF m_area; int m_cols = 1; int m_rows = 1; Cell m_start; Cell m_end; bool m_rightHeld = false; bool m_spaceHeld = false; QPointF m_grabOffset; QPointF m_cursor; // config, group "Effect-windowgrid" in kwinrc int m_cfgColumns = 6; int m_cfgRows = 4; bool m_useWorkArea = true; QColor m_gridColor; QColor m_selectionColor; qreal m_opacity = 0.35; }; } // namespace KWin