Screen Edges may belong to fullscreen windows
Corners are still ours (it's a valid use case to still be able to switch window through e.g. Present Windows even when running a fullscreen app). How is it done? An Edge can be blocked and does no longer trigger if it is blocked. For WindowBasedEdges the edge windows get unmapped in the blocking case and mapped again when the blocking condition is no longer valid. The blocking is so far connected to: * changes of active window * changes of fullscreen windows Whenever one of the events occurs it is checked whether there is: 1. an active client 2. it is fullscreen 3. on the same screen as the edge If this is the case the edge will be blocked, otherwise unblocked. BUG: 271607 FIXED-IN: 4.11
This commit is contained in:
parent
06895db1a9
commit
90eb2dbf05
3 changed files with 57 additions and 0 deletions
|
@ -60,6 +60,7 @@ Edge::Edge(ScreenEdges *parent)
|
||||||
, m_reserved(0)
|
, m_reserved(0)
|
||||||
, m_approaching(false)
|
, m_approaching(false)
|
||||||
, m_lastApproachingFactor(0.0)
|
, m_lastApproachingFactor(0.0)
|
||||||
|
, m_blocked(false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -102,6 +103,9 @@ void Edge::unreserve(QObject *object)
|
||||||
|
|
||||||
bool Edge::triggersFor(const QPoint &cursorPos) const
|
bool Edge::triggersFor(const QPoint &cursorPos) const
|
||||||
{
|
{
|
||||||
|
if (isBlocked()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
if (!m_geometry.contains(cursorPos)) {
|
if (!m_geometry.contains(cursorPos)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -316,6 +320,26 @@ void Edge::setGeometry(const QRect &geometry)
|
||||||
doGeometryUpdate();
|
doGeometryUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Edge::checkBlocking()
|
||||||
|
{
|
||||||
|
if (isCorner()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
bool newValue = false;
|
||||||
|
if (Client *client = Workspace::self()->activeClient()) {
|
||||||
|
newValue = client->isFullScreen() && client->geometry().contains(m_geometry.center());
|
||||||
|
}
|
||||||
|
if (newValue == m_blocked) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
m_blocked = newValue;
|
||||||
|
doUpdateBlocking();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Edge::doUpdateBlocking()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
void Edge::doGeometryUpdate()
|
void Edge::doGeometryUpdate()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -422,6 +446,7 @@ void WindowBasedEdge::activate()
|
||||||
{
|
{
|
||||||
createWindow();
|
createWindow();
|
||||||
createApproachWindow();
|
createApproachWindow();
|
||||||
|
doUpdateBlocking();
|
||||||
}
|
}
|
||||||
|
|
||||||
void WindowBasedEdge::deactivate()
|
void WindowBasedEdge::deactivate()
|
||||||
|
@ -499,6 +524,20 @@ void WindowBasedEdge::doStopApproaching()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WindowBasedEdge::doUpdateBlocking()
|
||||||
|
{
|
||||||
|
if (!isReserved()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (isBlocked()) {
|
||||||
|
xcb_unmap_window(connection(), m_window);
|
||||||
|
xcb_unmap_window(connection(), m_approachWindow);
|
||||||
|
} else {
|
||||||
|
xcb_map_window(connection(), m_window);
|
||||||
|
xcb_map_window(connection(), m_approachWindow);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**********************************************************
|
/**********************************************************
|
||||||
* ScreenEdges
|
* ScreenEdges
|
||||||
*********************************************************/
|
*********************************************************/
|
||||||
|
@ -872,6 +911,9 @@ WindowBasedEdge *ScreenEdges::createEdge(ElectricBorder border, int x, int y, in
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
connect(edge, SIGNAL(approaching(ElectricBorder,qreal,QRect)), SIGNAL(approaching(ElectricBorder,qreal,QRect)));
|
connect(edge, SIGNAL(approaching(ElectricBorder,qreal,QRect)), SIGNAL(approaching(ElectricBorder,qreal,QRect)));
|
||||||
|
if (edge->isScreenEdge()) {
|
||||||
|
connect(this, SIGNAL(checkBlocking()), edge, SLOT(checkBlocking()));
|
||||||
|
}
|
||||||
return edge;
|
return edge;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
11
screenedge.h
11
screenedge.h
|
@ -73,17 +73,20 @@ public Q_SLOTS:
|
||||||
void setAction(ElectricBorderAction action);
|
void setAction(ElectricBorderAction action);
|
||||||
void setGeometry(const QRect &geometry);
|
void setGeometry(const QRect &geometry);
|
||||||
void updateApproaching(const QPoint &point);
|
void updateApproaching(const QPoint &point);
|
||||||
|
void checkBlocking();
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
void approaching(ElectricBorder border, qreal factor, const QRect &geometry);
|
void approaching(ElectricBorder border, qreal factor, const QRect &geometry);
|
||||||
protected:
|
protected:
|
||||||
ScreenEdges *edges();
|
ScreenEdges *edges();
|
||||||
const ScreenEdges *edges() const;
|
const ScreenEdges *edges() const;
|
||||||
const QRect &geometry() const;
|
const QRect &geometry() const;
|
||||||
|
bool isBlocked() const;
|
||||||
virtual void doGeometryUpdate();
|
virtual void doGeometryUpdate();
|
||||||
virtual void activate();
|
virtual void activate();
|
||||||
virtual void deactivate();
|
virtual void deactivate();
|
||||||
virtual void doStartApproaching();
|
virtual void doStartApproaching();
|
||||||
virtual void doStopApproaching();
|
virtual void doStopApproaching();
|
||||||
|
virtual void doUpdateBlocking();
|
||||||
private:
|
private:
|
||||||
bool canActivate(const QPoint &cursorPos, const QDateTime &triggerTime);
|
bool canActivate(const QPoint &cursorPos, const QDateTime &triggerTime);
|
||||||
void handle(const QPoint &cursorPos);
|
void handle(const QPoint &cursorPos);
|
||||||
|
@ -103,6 +106,7 @@ private:
|
||||||
QHash<QObject *, QByteArray> m_callBacks;
|
QHash<QObject *, QByteArray> m_callBacks;
|
||||||
bool m_approaching;
|
bool m_approaching;
|
||||||
qreal m_lastApproachingFactor;
|
qreal m_lastApproachingFactor;
|
||||||
|
bool m_blocked;
|
||||||
};
|
};
|
||||||
|
|
||||||
class WindowBasedEdge : public Edge
|
class WindowBasedEdge : public Edge
|
||||||
|
@ -125,6 +129,7 @@ protected:
|
||||||
virtual void deactivate();
|
virtual void deactivate();
|
||||||
virtual void doStartApproaching();
|
virtual void doStartApproaching();
|
||||||
virtual void doStopApproaching();
|
virtual void doStopApproaching();
|
||||||
|
virtual void doUpdateBlocking();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void destroyWindow();
|
void destroyWindow();
|
||||||
|
@ -318,6 +323,7 @@ Q_SIGNALS:
|
||||||
**/
|
**/
|
||||||
void approaching(ElectricBorder border, qreal factor, const QRect &geometry);
|
void approaching(ElectricBorder border, qreal factor, const QRect &geometry);
|
||||||
void mousePollingTimerEvent(QPoint cursorPos);
|
void mousePollingTimerEvent(QPoint cursorPos);
|
||||||
|
void checkBlocking();
|
||||||
|
|
||||||
private Q_SLOTS:
|
private Q_SLOTS:
|
||||||
void performMousePoll();
|
void performMousePoll();
|
||||||
|
@ -443,6 +449,11 @@ inline const QHash< QObject *, QByteArray > &Edge::callBacks() const
|
||||||
return m_callBacks;
|
return m_callBacks;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline bool Edge::isBlocked() const
|
||||||
|
{
|
||||||
|
return m_blocked;
|
||||||
|
}
|
||||||
|
|
||||||
/**********************************************************
|
/**********************************************************
|
||||||
* Inlines WindowBasedEdge
|
* Inlines WindowBasedEdge
|
||||||
*********************************************************/
|
*********************************************************/
|
||||||
|
|
|
@ -267,6 +267,7 @@ void Workspace::init()
|
||||||
screenEdges->init();
|
screenEdges->init();
|
||||||
connect(options, SIGNAL(configChanged()), screenEdges, SLOT(reconfigure()));
|
connect(options, SIGNAL(configChanged()), screenEdges, SLOT(reconfigure()));
|
||||||
connect(VirtualDesktopManager::self(), SIGNAL(layoutChanged(int,int)), screenEdges, SLOT(updateLayout()));
|
connect(VirtualDesktopManager::self(), SIGNAL(layoutChanged(int,int)), screenEdges, SLOT(updateLayout()));
|
||||||
|
connect(this, SIGNAL(clientActivated(KWin::Client*)), screenEdges, SIGNAL(checkBlocking()));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
supportWindow = new QWidget(NULL, Qt::X11BypassWindowManagerHint);
|
supportWindow = new QWidget(NULL, Qt::X11BypassWindowManagerHint);
|
||||||
|
@ -567,6 +568,9 @@ Client* Workspace::createClient(Window w, bool is_mapped)
|
||||||
connect(c, SIGNAL(geometryChanged()), m_compositor, SLOT(checkUnredirect()));
|
connect(c, SIGNAL(geometryChanged()), m_compositor, SLOT(checkUnredirect()));
|
||||||
connect(c, SIGNAL(geometryShapeChanged(KWin::Toplevel*,QRect)), m_compositor, SLOT(checkUnredirect()));
|
connect(c, SIGNAL(geometryShapeChanged(KWin::Toplevel*,QRect)), m_compositor, SLOT(checkUnredirect()));
|
||||||
connect(c, SIGNAL(blockingCompositingChanged(KWin::Client*)), m_compositor, SLOT(updateCompositeBlocking(KWin::Client*)));
|
connect(c, SIGNAL(blockingCompositingChanged(KWin::Client*)), m_compositor, SLOT(updateCompositeBlocking(KWin::Client*)));
|
||||||
|
#ifdef KWIN_BUILD_SCREENEDGES
|
||||||
|
connect(c, SIGNAL(clientFullScreenSet(KWin::Client*,bool,bool)), ScreenEdges::self(), SIGNAL(checkBlocking()));
|
||||||
|
#endif
|
||||||
if (!c->manage(w, is_mapped)) {
|
if (!c->manage(w, is_mapped)) {
|
||||||
Client::deleteClient(c, Allowed);
|
Client::deleteClient(c, Allowed);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
Loading…
Reference in a new issue