KWin
Loading...
Searching...
No Matches
screenedge.h
Go to the documentation of this file.
1/*
2 KWin - the KDE window manager
3 This file is part of the KDE project.
4
5 SPDX-FileCopyrightText: 2011 Arthur Arlt <a.arlt@stud.uni-heidelberg.de>
6 SPDX-FileCopyrightText: 2013 Martin Gräßlin <mgraesslin@kde.org>
7
8 Since the functionality provided in this class has been moved from
9 class Workspace, it is not clear who exactly has written the code.
10 The list below contains the copyright holders of the class Workspace.
11
12 SPDX-FileCopyrightText: 1999, 2000 Matthias Ettrich <ettrich@kde.org>
13 SPDX-FileCopyrightText: 2003 Lubos Lunak <l.lunak@kde.org>
14 SPDX-FileCopyrightText: 2009 Lucas Murray <lmurray@undefinedfire.com>
15
16 SPDX-License-Identifier: GPL-2.0-or-later
17*/
18
19#pragma once
20// KWin
21#include "effect/globals.h"
22// KDE includes
23#include <KSharedConfig>
24// Qt
25#include <QDateTime>
26#include <QList>
27#include <QObject>
28#include <QRect>
29
30#include <memory>
31#include <xcb/xcb.h>
32
33class QAction;
34class QMouseEvent;
35
36namespace KWin
37{
38
39class Window;
40class Output;
41class GestureRecognizer;
42class ScreenEdges;
43class SwipeGesture;
44
46{
47public:
48 using CallbackFunction = std::function<void(ElectricBorder border, const QPointF &, Output *output)>;
51
52 QAction *touchUpAction() const;
53 void progressCallback(ElectricBorder border, const QPointF &deltaProgress, Output *output) const;
54 bool hasProgressCallback() const;
55
56private:
57 QAction *m_touchUpAction = nullptr;
58 TouchCallback::CallbackFunction m_progressCallback;
59};
60
61class KWIN_EXPORT Edge : public QObject
62{
63 Q_OBJECT
64public:
65 explicit Edge(ScreenEdges *parent);
66 ~Edge() override;
67 bool isLeft() const;
68 bool isTop() const;
69 bool isRight() const;
70 bool isBottom() const;
71 bool isCorner() const;
72 bool isScreenEdge() const;
73 bool triggersFor(const QPoint &cursorPos) const;
74 bool check(const QPoint &cursorPos, const QDateTime &triggerTime, bool forceNoPushBack = false);
75 void markAsTriggered(const QPoint &cursorPos, const QDateTime &triggerTime);
76 bool isReserved() const;
77 const QRect &approachGeometry() const;
78
79 ElectricBorder border() const;
80 void reserve(QObject *object, const char *slot);
81 const QHash<QObject *, QByteArray> &callBacks() const;
82 void reserveTouchCallBack(QAction *action, TouchCallback::CallbackFunction callback = nullptr);
83 void unreserveTouchCallBack(QAction *action);
84 void startApproaching();
85 void stopApproaching();
86 bool isApproaching() const;
87 void setClient(Window *client);
88 Window *client() const;
89 void setOutput(Output *output);
90 Output *output() const;
91 const QRect &geometry() const;
92 void setTouchAction(ElectricBorderAction action);
93
94 bool activatesForPointer() const;
95 bool activatesForTouchGesture() const;
96
101 virtual quint32 window() const;
108 virtual quint32 approachWindow() const;
109
110public Q_SLOTS:
111 void reserve();
112 void unreserve();
113 void unreserve(QObject *object);
114 void setBorder(ElectricBorder border);
115 void setAction(ElectricBorderAction action);
116 void setGeometry(const QRect &geometry);
117 void updateApproaching(const QPointF &point);
118 void checkBlocking();
119Q_SIGNALS:
120 void approaching(ElectricBorder border, qreal factor, const QRect &geometry);
122
123protected:
124 ScreenEdges *edges();
125 const ScreenEdges *edges() const;
126 bool isBlocked() const;
127 virtual void doGeometryUpdate();
128 virtual void doActivate();
129 virtual void doDeactivate();
130 virtual void doStartApproaching();
131 virtual void doStopApproaching();
132 virtual void doUpdateBlocking();
133
134private:
135 void activate();
136 void deactivate();
137 bool canActivate(const QPoint &cursorPos, const QDateTime &triggerTime);
138 void handle(const QPoint &cursorPos);
139 bool handleAction(ElectricBorderAction action);
140 bool handlePointerAction()
141 {
142 return handleAction(m_action);
143 }
144 bool handleTouchAction()
145 {
146 return handleAction(m_touchAction);
147 }
148 bool handleByCallback();
149 void handleTouchCallback();
150 void switchDesktop(const QPoint &cursorPos);
151 void pushCursorBack(const QPoint &cursorPos);
152 void reserveTouchCallBack(const TouchCallback &callback);
153 QList<TouchCallback> touchCallBacks() const
154 {
155 return m_touchCallbacks;
156 }
157 ScreenEdges *m_edges;
158 ElectricBorder m_border;
159 ElectricBorderAction m_action;
161 int m_reserved;
162 QRect m_geometry;
163 QRect m_approachGeometry;
164 QDateTime m_lastTrigger;
165 QDateTime m_lastReset;
166 QPoint m_triggeredPoint;
167 QHash<QObject *, QByteArray> m_callBacks;
168 bool m_approaching;
169 int m_lastApproachingFactor;
170 bool m_blocked;
171 bool m_pushBackBlocked;
172 Window *m_client;
173 Output *m_output;
174 std::unique_ptr<SwipeGesture> m_gesture;
175 QList<TouchCallback> m_touchCallbacks;
176 friend class ScreenEdges;
177};
178
221class KWIN_EXPORT ScreenEdges : public QObject
222{
223 Q_OBJECT
224 Q_PROPERTY(bool desktopSwitching READ isDesktopSwitching)
225 Q_PROPERTY(bool desktopSwitchingMovingClients READ isDesktopSwitchingMovingClients)
226 Q_PROPERTY(QSize cursorPushBackDistance READ cursorPushBackDistance)
227 Q_PROPERTY(int timeThreshold READ timeThreshold)
228 Q_PROPERTY(int reActivateThreshold READ reActivationThreshold)
229 Q_PROPERTY(int actionTopLeft READ actionTopLeft)
230 Q_PROPERTY(int actionTop READ actionTop)
231 Q_PROPERTY(int actionTopRight READ actionTopRight)
232 Q_PROPERTY(int actionRight READ actionRight)
233 Q_PROPERTY(int actionBottomRight READ actionBottomRight)
234 Q_PROPERTY(int actionBottom READ actionBottom)
235 Q_PROPERTY(int actionBottomLeft READ actionBottomLeft)
236 Q_PROPERTY(int actionLeft READ actionLeft)
237public:
242 void setConfig(KSharedConfig::Ptr config);
247 void init();
255 void check(const QPoint &pos, const QDateTime &now, bool forceNoPushBack = false);
259 int cornerOffset() const;
270 void reserve(ElectricBorder border, QObject *object, const char *callback);
281 void unreserve(ElectricBorder border, QObject *object);
301 bool reserve(KWin::Window *client, ElectricBorder border);
302
313 void reserveTouch(ElectricBorder border, QAction *action, TouchCallback::CallbackFunction callback = nullptr);
319 void unreserveTouch(ElectricBorder border, QAction *action);
320
326 void reserveDesktopSwitching(bool isToReserve, Qt::Orientations o);
331 void ensureOnTop();
332 bool isEntered(QMouseEvent *event);
333
338 QList<xcb_window_t> windows() const;
339
340 bool isDesktopSwitching() const;
341 bool isDesktopSwitchingMovingClients() const;
342 const QSize &cursorPushBackDistance() const;
346 int timeThreshold() const;
350 int reActivationThreshold() const;
351 ElectricBorderAction actionTopLeft() const;
352 ElectricBorderAction actionTop() const;
353 ElectricBorderAction actionTopRight() const;
354 ElectricBorderAction actionRight() const;
355 ElectricBorderAction actionBottomRight() const;
356 ElectricBorderAction actionBottom() const;
357 ElectricBorderAction actionBottomLeft() const;
358 ElectricBorderAction actionLeft() const;
359
360 ElectricBorderAction actionForTouchBorder(ElectricBorder border) const;
361
362 GestureRecognizer *gestureRecognizer() const
363 {
364 return m_gestureRecognizer;
365 }
366
367 bool handleDndNotify(xcb_window_t window, const QPoint &point);
368 bool handleEnterNotifiy(xcb_window_t window, const QPoint &point, const QDateTime &timestamp);
369 bool remainActiveOnFullscreen() const;
370 const std::vector<std::unique_ptr<Edge>> &edges() const;
371
372public Q_SLOTS:
373 void reconfigure();
378 void updateLayout();
382 void recreateEdges();
383
384Q_SIGNALS:
390 void approaching(ElectricBorder border, qreal factor, const QRect &geometry);
392
393private:
394 enum {
395 ElectricDisabled = 0,
396 ElectricMoveOnly = 1,
397 ElectricAlways = 2,
398 };
399 void setDesktopSwitching(bool enable);
400 void setDesktopSwitchingMovingClients(bool enable);
401 void setCursorPushBackDistance(const QSize &distance);
402 void setTimeThreshold(int threshold);
403 void setReActivationThreshold(int threshold);
404 void createHorizontalEdge(ElectricBorder border, const QRect &screen, const QRect &fullArea, Output *output);
405 void createVerticalEdge(ElectricBorder border, const QRect &screen, const QRect &fullArea, Output *output);
406 std::unique_ptr<Edge> createEdge(ElectricBorder border, int x, int y, int width, int height, Output *output, bool createAction = true);
407 void setActionForBorder(ElectricBorder border, ElectricBorderAction *oldValue, ElectricBorderAction newValue);
408 void setActionForTouchBorder(ElectricBorder border, ElectricBorderAction newValue);
409 void setRemainActiveOnFullscreen(bool remainActive);
410 ElectricBorderAction actionForEdge(Edge *edge) const;
411 ElectricBorderAction actionForTouchEdge(Edge *edge) const;
412 bool createEdgeForClient(Window *client, ElectricBorder border);
413 void deleteEdgeForClient(Window *client);
414 bool m_desktopSwitching;
415 bool m_desktopSwitchingMovingClients;
416 QSize m_cursorPushBackDistance;
417 int m_timeThreshold;
418 int m_reactivateThreshold;
419 Qt::Orientations m_virtualDesktopLayout;
420 std::vector<std::unique_ptr<Edge>> m_edges;
421 KSharedConfig::Ptr m_config;
422 ElectricBorderAction m_actionTopLeft;
423 ElectricBorderAction m_actionTop;
424 ElectricBorderAction m_actionTopRight;
425 ElectricBorderAction m_actionRight;
426 ElectricBorderAction m_actionBottomRight;
427 ElectricBorderAction m_actionBottom;
428 ElectricBorderAction m_actionBottomLeft;
429 ElectricBorderAction m_actionLeft;
430 QMap<ElectricBorder, ElectricBorderAction> m_touchCallbacks;
431 int m_cornerOffset;
432 GestureRecognizer *m_gestureRecognizer;
433 bool m_remainActiveOnFullscreen = false;
434};
435
436/**********************************************************
437 * Inlines Edge
438 *********************************************************/
439
440inline bool Edge::isBottom() const
441{
442 return m_border == ElectricBottom || m_border == ElectricBottomLeft || m_border == ElectricBottomRight;
443}
444
445inline bool Edge::isLeft() const
446{
447 return m_border == ElectricLeft || m_border == ElectricTopLeft || m_border == ElectricBottomLeft;
448}
449
450inline bool Edge::isRight() const
451{
452 return m_border == ElectricRight || m_border == ElectricTopRight || m_border == ElectricBottomRight;
453}
454
455inline bool Edge::isTop() const
456{
457 return m_border == ElectricTop || m_border == ElectricTopLeft || m_border == ElectricTopRight;
458}
459
460inline bool Edge::isCorner() const
461{
462 return m_border == ElectricTopLeft
463 || m_border == ElectricTopRight
464 || m_border == ElectricBottomRight
465 || m_border == ElectricBottomLeft;
466}
467
468inline bool Edge::isScreenEdge() const
469{
470 return m_border == ElectricLeft
471 || m_border == ElectricRight
472 || m_border == ElectricTop
473 || m_border == ElectricBottom;
474}
475
476inline bool Edge::isReserved() const
477{
478 return m_reserved != 0;
479}
480
482{
483 m_action = action;
484}
485
487{
488 return m_edges;
489}
490
491inline const ScreenEdges *Edge::edges() const
492{
493 return m_edges;
494}
495
496inline const QRect &Edge::geometry() const
497{
498 return m_geometry;
499}
500
501inline const QRect &Edge::approachGeometry() const
502{
503 return m_approachGeometry;
504}
505
507{
508 return m_border;
509}
510
511inline const QHash<QObject *, QByteArray> &Edge::callBacks() const
512{
513 return m_callBacks;
514}
515
516inline bool Edge::isBlocked() const
517{
518 return m_blocked;
519}
520
521inline Window *Edge::client() const
522{
523 return m_client;
524}
525
526inline bool Edge::isApproaching() const
527{
528 return m_approaching;
529}
530
531/**********************************************************
532 * Inlines ScreenEdges
533 *********************************************************/
534inline void ScreenEdges::setConfig(KSharedConfig::Ptr config)
535{
536 m_config = config;
537}
538
540{
541 return m_cornerOffset;
542}
543
544inline const QSize &ScreenEdges::cursorPushBackDistance() const
545{
546 return m_cursorPushBackDistance;
547}
548
550{
551 return m_desktopSwitching;
552}
553
555{
556 return m_desktopSwitchingMovingClients;
557}
558
560{
561 return m_reactivateThreshold;
562}
563
565{
566 return m_timeThreshold;
567}
568
569inline void ScreenEdges::setCursorPushBackDistance(const QSize &distance)
570{
571 m_cursorPushBackDistance = distance;
572}
573
574inline void ScreenEdges::setDesktopSwitching(bool enable)
575{
576 if (enable == m_desktopSwitching) {
577 return;
578 }
579 m_desktopSwitching = enable;
580 reserveDesktopSwitching(enable, m_virtualDesktopLayout);
581}
582
583inline void ScreenEdges::setDesktopSwitchingMovingClients(bool enable)
584{
585 m_desktopSwitchingMovingClients = enable;
586}
587
588inline void ScreenEdges::setReActivationThreshold(int threshold)
589{
590 Q_ASSERT(threshold >= m_timeThreshold);
591 m_reactivateThreshold = threshold;
592}
593
594inline void ScreenEdges::setTimeThreshold(int threshold)
595{
596 m_timeThreshold = threshold;
597}
598
599#define ACTION(name) \
600 inline ElectricBorderAction ScreenEdges::name() const \
601 { \
602 return m_##name; \
603 }
604
605ACTION(actionTopLeft)
606ACTION(actionTop)
607ACTION(actionTopRight)
608ACTION(actionRight)
609ACTION(actionBottomRight)
610ACTION(actionBottom)
611ACTION(actionBottomLeft)
612ACTION(actionLeft)
613
614#undef ACTION
615
616}
const QHash< QObject *, QByteArray > & callBacks() const
Definition screenedge.h:511
void setAction(ElectricBorderAction action)
Definition screenedge.h:481
bool isBottom() const
Definition screenedge.h:440
bool isScreenEdge() const
Definition screenedge.h:468
Window * client() const
Definition screenedge.h:521
bool isBlocked() const
Definition screenedge.h:516
bool isReserved() const
Definition screenedge.h:476
bool isLeft() const
Definition screenedge.h:445
void activatesForTouchGestureChanged()
bool isCorner() const
Definition screenedge.h:460
bool isApproaching() const
Definition screenedge.h:526
ScreenEdges * edges()
Definition screenedge.h:486
const QRect & geometry() const
Definition screenedge.h:496
const QRect & approachGeometry() const
Definition screenedge.h:501
ElectricBorder border() const
Definition screenedge.h:506
bool isTop() const
Definition screenedge.h:455
bool isRight() const
Definition screenedge.h:450
void approaching(ElectricBorder border, qreal factor, const QRect &geometry)
Class for controlling screen edges.
Definition screenedge.h:222
void approaching(ElectricBorder border, qreal factor, const QRect &geometry)
QSize cursorPushBackDistance
Definition screenedge.h:226
bool isDesktopSwitchingMovingClients() const
Definition screenedge.h:554
int cornerOffset() const
Definition screenedge.h:539
void setConfig(KSharedConfig::Ptr config)
Definition screenedge.h:534
int reActivationThreshold() const
Definition screenedge.h:559
void reserveDesktopSwitching(bool isToReserve, Qt::Orientations o)
bool isDesktopSwitching() const
Definition screenedge.h:549
TouchCallback(QAction *touchUpAction, TouchCallback::CallbackFunction progressCallback)
std::function< void(ElectricBorder border, const QPointF &, Output *output)> CallbackFunction
Definition screenedge.h:48
void progressCallback(ElectricBorder border, const QPointF &deltaProgress, Output *output) const
bool hasProgressCallback() const
QAction * touchUpAction() const
ElectricBorder
Definition globals.h:60
@ ElectricTopLeft
Definition globals.h:68
@ ElectricBottomLeft
Definition globals.h:66
@ ElectricBottom
Definition globals.h:65
@ ElectricTopRight
Definition globals.h:62
@ ElectricTop
Definition globals.h:61
@ ElectricRight
Definition globals.h:63
@ ElectricBottomRight
Definition globals.h:64
@ ElectricLeft
Definition globals.h:67
ElectricBorderAction
Definition globals.h:78
@ ElectricActionNone
Definition globals.h:79
#define ACTION(name)
Definition screenedge.h:599
#define explicit