Skip to content

Commit 961cd34

Browse files
authored
Merge pull request #118 from shinnkka/main
Replace org.freedesktop.ScreenSaver with org.freedesktop.portal.Inhibit
2 parents 9d3257c + 8397e20 commit 961cd34

4 files changed

Lines changed: 346 additions & 37 deletions

File tree

.github/workflows/checks.yml

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -351,29 +351,40 @@ jobs:
351351
libgtk-3-dev liblzma-dev xvfb dbus-x11 \
352352
python3-dbus python3-gi
353353
354+
- name: Run Linux Unit Tests
355+
run: |
356+
cd wakelock_plus
357+
flutter pub get
358+
flutter test test/wakelock_plus_linux_plugin_test.dart
359+
354360
- name: Run Integration Tests
355361
run: |
356362
flutter config --enable-linux-desktop
357363
cd wakelock_plus/example
358364
flutter pub get
359365
360366
# We use xvfb-run (display) and dbus-run-session (bus).
361-
# Inside, we run a Python mock of 'org.freedesktop.ScreenSaver' so the plugin logic succeeds.
367+
# Inside, we run a Python mock of 'org.freedesktop.portal.Desktop' so the plugin logic succeeds.
362368
xvfb-run dbus-run-session bash -c "
363369
python3 -c \"
364370
import dbus, dbus.service
365371
from dbus.mainloop.glib import DBusGMainLoop
366372
from gi.repository import GLib
367-
class Mock(dbus.service.Object):
368-
def __init__(self):
369-
bus_name = dbus.service.BusName('org.freedesktop.ScreenSaver', bus=dbus.SessionBus())
370-
dbus.service.Object.__init__(self, bus_name, '/org/freedesktop/ScreenSaver')
371-
@dbus.service.method('org.freedesktop.ScreenSaver', in_signature='ss', out_signature='u')
372-
def Inhibit(self, a, r): return 1
373-
@dbus.service.method('org.freedesktop.ScreenSaver', in_signature='u', out_signature='')
374-
def UnInhibit(self, c): pass
373+
class RequestMock(dbus.service.Object):
374+
def __init__(self, bus):
375+
dbus.service.Object.__init__(self, bus, '/org/freedesktop/portal/desktop/request/1_1/test')
376+
@dbus.service.method('org.freedesktop.portal.Request', in_signature='', out_signature='')
377+
def Close(self): pass
378+
class DesktopMock(dbus.service.Object):
379+
def __init__(self, bus):
380+
bus_name = dbus.service.BusName('org.freedesktop.portal.Desktop', bus=bus)
381+
dbus.service.Object.__init__(self, bus_name, '/org/freedesktop/portal/desktop')
382+
@dbus.service.method('org.freedesktop.portal.Inhibit', in_signature='sua{sv}', out_signature='o')
383+
def Inhibit(self, window, flags, options): return dbus.ObjectPath('/org/freedesktop/portal/desktop/request/1_1/test')
375384
DBusGMainLoop(set_as_default=True)
376-
Mock()
385+
bus = dbus.SessionBus()
386+
DesktopMock(bus)
387+
RequestMock(bus)
377388
GLib.MainLoop().run()\" &
378389
sleep 5 && \
379390
flutter drive \

wakelock_plus/lib/src/wakelock_plus_linux_plugin.dart

Lines changed: 55 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -8,54 +8,84 @@ import 'package:wakelock_plus_platform_interface/wakelock_plus_platform_interfac
88
/// The Linux implementation of the [WakelockPlusPlatformInterface].
99
///
1010
/// This class implements the `wakelock_plus` plugin functionality for Linux
11-
/// using the `org.freedesktop.ScreenSaver` D-Bus API
12-
/// (see https://specifications.freedesktop.org/idle-inhibit-spec/latest/re01.html).
11+
/// using the `org.freedesktop.portal.Inhibit` D-Bus API
12+
/// (see https://flatpak.github.io/xdg-desktop-portal/docs/doc-org.freedesktop.portal.Inhibit).
1313
class WakelockPlusLinuxPlugin extends WakelockPlusPlatformInterface {
1414
/// Registers this class as the default instance of [WakelockPlatformInterface].
1515
static void registerWith() {
1616
WakelockPlusPlatformInterface.instance = WakelockPlusLinuxPlugin();
1717
}
1818

1919
/// Constructs an instance of [WakelockPlusLinuxPlugin].
20-
WakelockPlusLinuxPlugin({@visibleForTesting DBusRemoteObject? object})
21-
: _object = object ?? _createRemoteObject();
22-
23-
final DBusRemoteObject _object;
24-
int? _cookie;
25-
26-
static DBusRemoteObject _createRemoteObject() {
27-
return DBusRemoteObject(
28-
DBusClient.session(),
29-
name: 'org.freedesktop.ScreenSaver',
30-
path: DBusObjectPath('/org/freedesktop/ScreenSaver'),
20+
factory WakelockPlusLinuxPlugin({
21+
@visibleForTesting DBusClient? client,
22+
@visibleForTesting DBusRemoteObject? object,
23+
@visibleForTesting Future<String> Function()? appNameGetter,
24+
}) {
25+
final dbusClient = client ?? DBusClient.session();
26+
final remoteObject =
27+
object ??
28+
DBusRemoteObject(
29+
dbusClient,
30+
name: 'org.freedesktop.portal.Desktop',
31+
path: DBusObjectPath('/org/freedesktop/portal/desktop'),
32+
);
33+
return WakelockPlusLinuxPlugin._internal(
34+
dbusClient,
35+
remoteObject,
36+
appNameGetter,
3137
);
3238
}
3339

40+
WakelockPlusLinuxPlugin._internal(
41+
this._client,
42+
this._object,
43+
this._appNameGetter,
44+
);
45+
46+
final DBusClient _client;
47+
final DBusRemoteObject _object;
48+
final Future<String> Function()? _appNameGetter;
49+
DBusObjectPath? _requestHandle;
50+
3451
Future<String> get _appName =>
52+
_appNameGetter?.call() ??
3553
PackageInfo.fromPlatform().then((info) => info.appName);
3654

3755
@override
3856
Future<void> toggle({required bool enable}) async {
3957
if (enable) {
40-
_cookie = await _object
58+
final appName = await _appName;
59+
_requestHandle = await _object
4160
.callMethod(
42-
'org.freedesktop.ScreenSaver',
61+
'org.freedesktop.portal.Inhibit',
4362
'Inhibit',
44-
[DBusString(await _appName), const DBusString('wakelock')],
45-
replySignature: DBusSignature.uint32,
63+
[
64+
const DBusString(''),
65+
const DBusUint32(8),
66+
DBusDict.stringVariant({
67+
'reason': DBusString('$appName: wakelock active'),
68+
}),
69+
],
70+
replySignature: DBusSignature('o'),
4671
)
47-
.then((response) => response.returnValues.single.asUint32());
48-
} else if (_cookie != null) {
49-
await _object.callMethod(
50-
'org.freedesktop.ScreenSaver',
51-
'UnInhibit',
52-
[DBusUint32(_cookie!)],
72+
.then((response) => response.returnValues.single.asObjectPath());
73+
} else if (_requestHandle != null) {
74+
final requestObject = DBusRemoteObject(
75+
_client,
76+
name: 'org.freedesktop.portal.Desktop',
77+
path: _requestHandle!,
78+
);
79+
await requestObject.callMethod(
80+
'org.freedesktop.portal.Request',
81+
'Close',
82+
[],
5383
replySignature: DBusSignature.empty,
5484
);
55-
_cookie = null;
85+
_requestHandle = null;
5686
}
5787
}
5888

5989
@override
60-
Future<bool> get enabled async => _cookie != null;
90+
Future<bool> get enabled async => _requestHandle != null;
6191
}

wakelock_plus/pubspec.yaml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,8 @@ dev_dependencies:
3333
sdk: flutter
3434
flutter_lints: ^6.0.0
3535
pigeon: ^26.2.3 # dart run pigeon --input "pigeons/messages.dart"
36-
36+
mocktail: ^1.0.4
37+
3738
# For information on the generic Dart part of this file, see the
3839
# following page: https://dart.dev/tools/pub/pubspec
3940

@@ -99,4 +100,4 @@ flutter:
99100
# https://flutter.dev/custom-fonts/#from-packages
100101

101102
assets:
102-
- packages/wakelock_plus/assets/no_sleep.js
103+
- packages/wakelock_plus/assets/no_sleep.js

0 commit comments

Comments
 (0)