Skip to content

Commit

Permalink
feat: support idlenotify idleinhibit and outputpowermanagement
Browse files Browse the repository at this point in the history
Log: protocols used for idle behavior such as screen blanking, locking, and screensaving
  • Loading branch information
wineee committed Feb 18, 2025
1 parent c66f8dc commit 7d56597
Show file tree
Hide file tree
Showing 2 changed files with 95 additions and 0 deletions.
82 changes: 82 additions & 0 deletions src/seat/helper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@
#include <wxdgshell.h>

Check warning on line 59 in src/seat/helper.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <wxdgshell.h> not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <wxwayland.h>

Check warning on line 60 in src/seat/helper.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <wxwayland.h> not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <wxwaylandsurface.h>

Check warning on line 61 in src/seat/helper.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <wxwaylandsurface.h> not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <wxdgtoplevelsurface.h>

Check warning on line 62 in src/seat/helper.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <wxdgtoplevelsurface.h> not found. Please note: Cppcheck does not need standard library headers to get proper results.

#include <qwallocator.h>

Check warning on line 64 in src/seat/helper.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <qwallocator.h> not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <qwbackend.h>

Check warning on line 65 in src/seat/helper.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <qwbackend.h> not found. Please note: Cppcheck does not need standard library headers to get proper results.
Expand All @@ -77,6 +78,9 @@
#include <qwsubcompositor.h>

Check warning on line 78 in src/seat/helper.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <qwsubcompositor.h> not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <qwviewporter.h>

Check warning on line 79 in src/seat/helper.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <qwviewporter.h> not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <qwxwaylandsurface.h>

Check warning on line 80 in src/seat/helper.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <qwxwaylandsurface.h> not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <qwoutputpowermanagementv1.h>

Check warning on line 81 in src/seat/helper.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <qwoutputpowermanagementv1.h> not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <qwidlenotifyv1.h>
#include <qwidleinhibitv1.h>

#include <QAction>
#include <QKeySequence>
Expand Down Expand Up @@ -468,6 +472,71 @@ void Helper::onOutputTestOrApply(qw_output_configuration_v1 *config, bool onlyTe
m_outputManager->sendResult(config, ok);
}

void Helper::onSetOutputPowerMode(wlr_output_power_v1_set_mode_event *event)
{
auto output = qw_output::from(event->output);
qw_output_state newState;

switch (event->mode) {
case ZWLR_OUTPUT_POWER_V1_MODE_OFF:
if (!output->handle()->enabled) {
return;
}
newState.set_enabled(false);
output->commit_state(newState);
break;
case ZWLR_OUTPUT_POWER_V1_MODE_ON:
if (output->handle()->enabled) {
return;
}
newState.set_enabled(true);
output->commit_state(newState);
break;
}
}

void Helper::onNewIdleInhibitor(wlr_idle_inhibitor_v1 *wlr_inhibitor)
{
auto inhibitor = qw_idle_inhibitor_v1::from(wlr_inhibitor);
m_idleInhibitors.append(inhibitor);

connect(inhibitor, &qw_idle_inhibitor_v1::before_destroy, this, [this, inhibitor]() {
m_idleInhibitors.removeOne(inhibitor);
updateIdleInhibitor();
});

auto wsurface = WSurface::fromHandle(wlr_inhibitor->surface);
connect(wsurface, &WSurface::mappedChanged, inhibitor, [this]() {
updateIdleInhibitor();
});

auto toplevel = WXdgToplevelSurface::fromSurface(wsurface);
if (toplevel) {
connect(toplevel, &WXdgToplevelSurface::minimizeChanged, inhibitor, [this]() {
updateIdleInhibitor();
});
}

updateIdleInhibitor();
}

void Helper::updateIdleInhibitor()
{
for (const auto &inhibitor : std::as_const(m_idleInhibitors)) {
auto wsurface = WSurface::fromHandle((*inhibitor)->surface);
bool visible = wsurface->mapped();
auto toplevel = WXdgToplevelSurface::fromSurface(wsurface);
if (toplevel)
visible &= !toplevel->isMinimized();

if (visible) {
m_idleNotifier->set_inhibited(true);
return;
}
}
m_idleNotifier->set_inhibited(false);
}

void Helper::onDockPreview(std::vector<SurfaceWrapper *> surfaces,
WSurface *target,
QPoint pos,
Expand Down Expand Up @@ -994,6 +1063,16 @@ void Helper::init()
QMetaObject::invokeMethod(m_dockPreview, "close");
});


m_idleNotifier = qw_idle_notifier_v1::create(*m_server->handle());

m_idleInhibitManager = qw_idle_inhibit_manager_v1::create(*m_server->handle());
connect(m_idleInhibitManager, &qw_idle_inhibit_manager_v1::notify_new_inhibitor, this, &Helper::onNewIdleInhibitor);

m_outputPowerManager = qw_output_power_manager_v1::create(*m_server->handle());

connect(m_outputPowerManager, &qw_output_power_manager_v1::notify_set_mode, this, &Helper::onSetOutputPowerMode);

m_backend->handle()->start();

qCInfo(qLcHelper) << "Listing on:" << m_socket->fullServerName();
Expand Down Expand Up @@ -1080,6 +1159,9 @@ void Helper::fakePressSurfaceBottomRightToReszie(SurfaceWrapper *surface)

bool Helper::beforeDisposeEvent(WSeat *seat, QWindow *, QInputEvent *event)
{
if (event->isInputEvent()) {
m_idleNotifier->notify_activity(seat->nativeHandle());
}
// NOTE: Unable to distinguish meta from other key combinations
// For example, Meta+S will still receive Meta release after
// fully releasing the key, actively detect whether there are
Expand Down
13 changes: 13 additions & 0 deletions src/seat/helper.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,11 @@ QW_BEGIN_NAMESPACE
class qw_renderer;
class qw_allocator;
class qw_compositor;
class qw_idle_notifier_v1;
class qw_idle_inhibit_manager_v1;
class qw_output_configuration_v1;
class qw_output_power_manager_v1;
class qw_idle_inhibitor_v1;
QW_END_NAMESPACE

WAYLIB_SERVER_USE_NAMESPACE
Expand Down Expand Up @@ -84,6 +88,8 @@ class IMultitaskView;
class LockScreenInterface;
class ILockScreen;
class UserModel;
struct wlr_idle_inhibitor_v1;
struct wlr_output_power_v1_set_mode_event;

class Helper : public WSeatEventFilter
{
Expand Down Expand Up @@ -220,6 +226,8 @@ private Q_SLOTS:
void onSurfaceModeChanged(WSurface *surface, WXdgDecorationManager::DecorationMode mode);
void setGamma(struct wlr_gamma_control_manager_v1_set_gamma_event *event);
void onOutputTestOrApply(qw_output_configuration_v1 *config, bool onlyTest);
void onSetOutputPowerMode(wlr_output_power_v1_set_mode_event *event);
void onNewIdleInhibitor(wlr_idle_inhibitor_v1 *inhibitor);
void onDockPreview(std::vector<SurfaceWrapper *> surfaces,
WSurface *target,
QPoint pos,
Expand Down Expand Up @@ -272,6 +280,7 @@ private Q_SLOTS:
bool isNvidiaCardPresent();
void setWorkspaceVisible(bool visible);
void restoreFromShowDesktop(SurfaceWrapper *activeSurface = nullptr);
void updateIdleInhibitor();

static Helper *m_instance;

Expand All @@ -295,6 +304,9 @@ private Q_SLOTS:

// protocols
qw_compositor *m_compositor = nullptr;
qw_idle_notifier_v1 *m_idleNotifier = nullptr;
qw_idle_inhibit_manager_v1 *m_idleInhibitManager = nullptr;
qw_output_power_manager_v1 *m_outputPowerManager = nullptr;
ShellHandler *m_shellHandler = nullptr;
WXWayland *m_defaultXWayland = nullptr;
WXdgDecorationManager *m_xdgDecorationManager = nullptr;
Expand All @@ -313,6 +325,7 @@ private Q_SLOTS:
// private data
QList<Output *> m_outputList;
QPointer<QQuickItem> m_taskSwitch;
QList<qw_idle_inhibitor_v1 *> m_idleInhibitors;

SurfaceWrapper *m_activatedSurface = nullptr;
RootSurfaceContainer *m_rootSurfaceContainer = nullptr;
Expand Down

0 comments on commit 7d56597

Please sign in to comment.