Skip to content

Commit 77c3702

Browse files
authored
Merge pull request #4538 from andydotxyz/feature/blockscreenlock
Support disabling the screen blank/lock
2 parents d2e075e + c16afc6 commit 77c3702

10 files changed

+97
-0
lines changed

driver.go

+5
Original file line numberDiff line numberDiff line change
@@ -37,4 +37,9 @@ type Driver interface {
3737
//
3838
// Since: 2.5
3939
DoubleTapDelay() time.Duration
40+
41+
// SetDisableScreenBlanking allows an app to ask the device not to sleep/lock/blank displays
42+
//
43+
// Since: 2.5
44+
SetDisableScreenBlanking(bool)
4045
}

internal/driver/glfw/driver.go

+4
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,10 @@ func (d *gLDriver) DoubleTapDelay() time.Duration {
169169
return doubleTapDelay
170170
}
171171

172+
func (d *gLDriver) SetDisableScreenBlanking(bool) {
173+
// TODO implement for Windows, macOS, X11 and Wayland
174+
}
175+
172176
// NewGLDriver sets up a new Driver instance implemented using the GLFW Go library and OpenGL bindings.
173177
func NewGLDriver() *gLDriver {
174178
repository.Register("file", intRepo.NewFileRepository())

internal/driver/mobile/android.c

+22
Original file line numberDiff line numberDiff line change
@@ -480,3 +480,25 @@ char* listURI(uintptr_t jni_env, uintptr_t ctx, char* uriCstr) {
480480
LOG_FATAL("Unrecognized scheme: %s", uriCstr);
481481
return "";
482482
}
483+
484+
void keepScreenOn(uintptr_t jni_env, uintptr_t ctx, bool disabled) {
485+
JNIEnv *env = (JNIEnv*)jni_env;
486+
jclass activityClass = find_class(env, "android/app/Activity");
487+
jmethodID getWindow = find_method(env, activityClass, "getWindow", "()Landroid/view/Window;");
488+
489+
jobject win = (*env)->CallObjectMethod(env, (jobject)ctx, getWindow);
490+
jclass windowClass = find_class(env, "android/view/Window");
491+
492+
jmethodID action = NULL;
493+
if (disabled) {
494+
action = find_method(env, windowClass, "addFlags", "(I)V");
495+
} else {
496+
action = find_method(env, windowClass, "clearFlags", "(I)V");
497+
}
498+
499+
jclass paramsClass = find_class(env, "android/view/WindowManager$LayoutParams" );
500+
jfieldID screenFlagField = (*env)->GetStaticFieldID(env, paramsClass, "FLAG_KEEP_SCREEN_ON", "I" );
501+
int screenFlag = (*env)->GetStaticIntField(env, paramsClass, screenFlagField);
502+
503+
(*env)->CallVoidMethod(env, win, action, screenFlag);
504+
}

internal/driver/mobile/device_desktop.go

+4
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,7 @@ const tapYOffset = 0 // no finger compensation on desktop (simulation)
99
func (*device) SystemScaleForWindow(_ fyne.Window) float32 {
1010
return 2 // this is simply due to the high number of pixels on a mobile device - just an approximation
1111
}
12+
13+
func setDisableScreenBlank(_ bool) {
14+
// ignore in mobile simulation mode
15+
}

internal/driver/mobile/device_wayland.go

+4
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,7 @@ const tapYOffset = -4.0 // to compensate for how we hold our fingers on the devi
99
func (*device) SystemScaleForWindow(_ fyne.Window) float32 {
1010
return 1 // PinePhone simplification, our only wayland mobile currently
1111
}
12+
13+
func setDisableScreenBlank(_ bool) {
14+
// ignore in mobile simulation mode
15+
}

internal/driver/mobile/driver.go

+4
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,10 @@ func (d *mobileDriver) Run() {
220220
})
221221
}
222222

223+
func (*mobileDriver) SetDisableScreenBlanking(disable bool) {
224+
setDisableScreenBlank(disable)
225+
}
226+
223227
func (d *mobileDriver) handleLifecycle(e lifecycle.Event, w fyne.Window) {
224228
c := w.Canvas().(*mobileCanvas)
225229
switch e.Crosses(lifecycle.StageVisible) {
+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
//go:build android
2+
3+
package mobile
4+
5+
import "fyne.io/fyne/v2/driver"
6+
7+
/*
8+
#include <stdbool.h>
9+
#include <stdlib.h>
10+
11+
void keepScreenOn(uintptr_t jni_env, uintptr_t ctx, bool disabled);
12+
*/
13+
import "C"
14+
15+
func setDisableScreenBlank(disable bool) {
16+
driver.RunNative(func(ctx any) error {
17+
ac := ctx.(*driver.AndroidContext)
18+
19+
C.keepScreenOn(C.uintptr_t(ac.Env), C.uintptr_t(ac.Ctx), C.bool(disable))
20+
21+
return nil
22+
})
23+
}

internal/driver/mobile/driver_ios.go

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
//go:build ios
2+
3+
package mobile
4+
5+
/*
6+
#cgo darwin LDFLAGS: -framework UIKit
7+
#import <Foundation/Foundation.h>
8+
9+
void disableIdleTimer(BOOL disabled);
10+
*/
11+
import "C"
12+
13+
func setDisableScreenBlank(disable bool) {
14+
C.disableIdleTimer(C.BOOL(disable))
15+
}

internal/driver/mobile/driver_ios.m

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
//go:build ios
2+
3+
#import <Foundation/Foundation.h>
4+
#import <UIKit/UIKit.h>
5+
6+
void disableIdleTimer(BOOL disabled) {
7+
@autoreleasepool {
8+
[[NSOperationQueue mainQueue] addOperationWithBlock:^ {
9+
[UIApplication sharedApplication].idleTimerDisabled = disabled;
10+
}];
11+
}
12+
}

test/testdriver.go

+4
Original file line numberDiff line numberDiff line change
@@ -134,3 +134,7 @@ func (d *testDriver) removeWindow(w *testWindow) {
134134
func (d *testDriver) DoubleTapDelay() time.Duration {
135135
return 300 * time.Millisecond
136136
}
137+
138+
func (d *testDriver) SetDisableScreenBlanking(_ bool) {
139+
// no-op for test
140+
}

0 commit comments

Comments
 (0)