Implement plasma-surface open-under-cursor

The surface is positioned at the current cursor location but kept in
bounds to keep it fully visible when the cursor is near the screen border.
remotes/origin/work/arichardson/reduce-gbm-code-dup
David Redondo 4 years ago
parent 0130b53126
commit d548f4bce4
  1. 16
      src/wayland/plasmashell_interface.cpp
  2. 11
      src/wayland/plasmashell_interface.h
  3. 20
      src/xdgshellwindow.cpp

@ -46,6 +46,7 @@ public:
bool m_skipTaskbar = false;
bool m_skipSwitcher = false;
bool m_panelTakesFocus = false;
bool m_openUnderCursorRequested = false;
private:
void org_kde_plasma_surface_destroy_resource(Resource *resource) override;
@ -59,6 +60,7 @@ private:
void org_kde_plasma_surface_panel_auto_hide_show(Resource *resource) override;
void org_kde_plasma_surface_set_panel_takes_focus(Resource *resource, uint32_t takes_focus) override;
void org_kde_plasma_surface_set_skip_switcher(Resource *resource, uint32_t skip) override;
void org_kde_plasma_surface_open_under_cursor(Resource *resource) override;
};
PlasmaShellInterface::PlasmaShellInterface(Display *display, QObject *parent)
@ -148,6 +150,15 @@ void PlasmaShellSurfaceInterfacePrivate::org_kde_plasma_surface_set_position(Res
Q_EMIT q->positionChanged();
}
void PlasmaShellSurfaceInterfacePrivate::org_kde_plasma_surface_open_under_cursor(Resource *resource)
{
if (surface && surface->buffer()) {
wl_resource_post_error(resource->handle, -1, "open_under_cursor: surface has a buffer");
}
m_openUnderCursorRequested = true;
Q_EMIT q->openUnderCursorRequested();
}
void PlasmaShellSurfaceInterfacePrivate::org_kde_plasma_surface_set_role(Resource *resource, uint32_t role)
{
Q_UNUSED(resource)
@ -272,6 +283,11 @@ bool PlasmaShellSurfaceInterface::isPositionSet() const
return d->m_positionSet;
}
bool PlasmaShellSurfaceInterface::wantsOpenUnderCursor() const
{
return d->m_openUnderCursorRequested;
}
PlasmaShellSurfaceInterface::PanelBehavior PlasmaShellSurfaceInterface::panelBehavior() const
{
return d->m_panelBehavior;

@ -74,6 +74,11 @@ public:
*/
bool isPositionSet() const;
/**
* @returns Whether the surface has requested to be opened under the cursor.
*/
bool wantsOpenUnderCursor() const;
/**
* Describes possible roles this PlasmaShellSurfaceInterface can have.
* The role can be used by the server to e.g. change the stacking order accordingly.
@ -159,6 +164,12 @@ Q_SIGNALS:
* A change of global position has been requested.
*/
void positionChanged();
/**
* The surface has requested to be initially shown under the cursor. Can only occur
* before any buffer has been attached.
*/
void openUnderCursorRequested();
/**
* A change of the role has been requested.
*/

@ -438,6 +438,17 @@ void XdgSurfaceWindow::installPlasmaShellSurface(PlasmaShellSurfaceInterface *sh
auto updatePosition = [this, shellSurface] {
move(shellSurface->position());
};
auto moveUnderCursor = [this, shellSurface] {
// Wait for the first commit
auto connection = new QMetaObject::Connection;
*connection = connect(this, &Window::windowShown, [this, connection] () {
disconnect(*connection);
if (input()->hasPointer()) {
move(input()->globalPointer().toPoint());
keepInArea(workspace()->clientArea(PlacementArea, this));
}
});
};
auto updateRole = [this, shellSurface] {
NET::WindowType type = NET::Unknown;
switch (shellSurface->role()) {
@ -486,6 +497,7 @@ void XdgSurfaceWindow::installPlasmaShellSurface(PlasmaShellSurfaceInterface *sh
workspace()->updateClientArea();
};
connect(shellSurface, &PlasmaShellSurfaceInterface::positionChanged, this, updatePosition);
connect(shellSurface, &PlasmaShellSurfaceInterface::openUnderCursorRequested, this, moveUnderCursor);
connect(shellSurface, &PlasmaShellSurfaceInterface::roleChanged, this, updateRole);
connect(shellSurface, &PlasmaShellSurfaceInterface::panelBehaviorChanged, this, [this] {
updateShowOnScreenEdge();
@ -511,6 +523,9 @@ void XdgSurfaceWindow::installPlasmaShellSurface(PlasmaShellSurfaceInterface *sh
if (shellSurface->isPositionSet()) {
updatePosition();
}
if (shellSurface->wantsOpenUnderCursor()) {
moveUnderCursor();
}
updateRole();
updateShowOnScreenEdge();
connect(this, &XdgSurfaceWindow::frameGeometryChanged,
@ -707,7 +722,10 @@ bool XdgToplevelWindow::isMinimizable() const
bool XdgToplevelWindow::isPlaceable() const
{
return !m_plasmaShellSurface || !m_plasmaShellSurface->isPositionSet();
if (m_plasmaShellSurface) {
return !m_plasmaShellSurface->isPositionSet() && !m_plasmaShellSurface->wantsOpenUnderCursor();
}
return true;
}
bool XdgToplevelWindow::isTransient() const

Loading…
Cancel
Save