SDL_PollEvent导致xset dpms强制关闭后屏幕唤醒
SDL_PollEvent causes screen to wake up after xset dpms force off
我有一个程序,可以用xset dpms force on/off
打开和关闭屏幕,并在循环中调用SDL_PollEvent(&e)
。在用xset
关闭显示后,任何对SDL_PollEvent
的调用都会导致屏幕唤醒,即使没有任何输入。我可以注释出SDL_PollEvent
调用,它不会发生。我是否需要做一些事情来处理事件或阻止屏幕打开?用最少的代码更新以重现问题:
#include <GL/glew.h>
#include <SDL2/SDL.h>
#include <atomic>
#include <iostream>
#include <thread>
using namespace std;
atomic<bool> SCREEN_ON(true);
atomic<bool> RUNNING(true);
atomic<bool> SERVER_CONNECTED(false);
std::string exec(const char *cmd) {
char buffer[128];
std::string result = "";
std::shared_ptr<FILE> pipe(popen(cmd, "r"), pclose);
if (!pipe)
throw std::runtime_error("popen() failed!");
while (!feof(pipe.get())) {
if (fgets(buffer, 128, pipe.get()) != NULL)
result += buffer;
}
return result;
}
double get_time() {
static const Uint64 freq = SDL_GetPerformanceFrequency();
static const Uint64 begin_time = SDL_GetPerformanceCounter();
Uint64 current = SDL_GetPerformanceCounter();
Uint64 elapsed = current - begin_time;
return (double)elapsed / (double)freq;
}
void handle_input() {
SDL_Event e;
while (SDL_PollEvent(&e)){}
}
void monitor_thread() {
while (RUNNING) {
double time = get_time();
if (time < 15)
SERVER_CONNECTED = false;
else if (time < 35)
SERVER_CONNECTED = true;
else
SERVER_CONNECTED = false;
cout << "server status: " << SERVER_CONNECTED << endl;
cout << "screen_on status: " << SCREEN_ON << endl;
handle_input();
SDL_Delay(1000);
if (SCREEN_ON && (!SERVER_CONNECTED)) {
cout << "TURNING SCREEN OFFn";
SCREEN_ON = false;
exec("sleep 1 && xset -display :0.0 dpms force off");
}
if ((!SCREEN_ON) && SERVER_CONNECTED) {
cout << "TURNING SCREEN ONn";
SCREEN_ON = true;
exec("sleep 1 && xset -display :0.0 dpms force on");
}
}
}
int main(int argc, char *argv[]) {
Uint32 initflags = SDL_INIT_TIMER | SDL_INIT_VIDEO;
SDL_Init(initflags);
Uint32 window_flags =
SDL_WINDOW_FULLSCREEN | SDL_WINDOW_OPENGL | SDL_WINDOW_INPUT_GRABBED;
SDL_Window *window =
SDL_CreateWindow("title", 25, 25, 800, 600, window_flags);
SDL_SetRelativeMouseMode(SDL_TRUE);
SDL_EnableScreenSaver();
SDL_GLContext gl_context = SDL_GL_CreateContext(window);
glewInit();
thread update_thread(monitor_thread);
glClearColor(1, 1, 0, 0);
glClear(GL_COLOR_BUFFER_BIT);
while (RUNNING) {
if (!SCREEN_ON) {
cout << "zzz...n";
SDL_Delay(2000);
continue;
}
glClear(GL_COLOR_BUFFER_BIT);
SDL_Delay(16);
SDL_GL_SwapWindow(window);
}
return 0;
}
在exec("sleep 1 && xset -display :0.0 dpms force off");
之后不久,在下一次调用将其重新打开之前,屏幕将自行打开。
别介意,SDL_PollEvent只能在主线程中调用。
呼叫SDL_EnableScreenSaver()
。
更多信息:
为什么SDL默认禁用我的屏保?
许多使用SDL的应用程序是游戏、屏保或媒体播放器用户要么长时间观看某样东西,要么长时间观看某样东西时间或使用摇杆输入,一般不防止屏保启动
您可以通过设置环境变量来禁用此行为:
SDL_VIDEO_ALLOW_SCREENSAVER=1
可以为用户或全局设置
在SDL 2.0.2中,这也可以通过设置提示来更改SDL_HINT_VIDEO_ALLOW_SCREENSAVER
.
另外,SDL 2.0提供了SDL_EnableScreenSaver()
函数。
相关文章:
- UE4-如何在给定4个屏幕坐标的情况下缩放纹理或材质
- 如何在GTK程序运行时禁用屏幕保护程序/电源管理/屏幕消隐
- 使用 SFML 和 C++ 将 Pixel 打印到屏幕上
- 在 Windows 8/10 技术中完全实时的屏幕捕获,没有延迟
- Winapi:屏幕截图未显示在窗口中
- 如何在快板的屏幕中显示子位图的绘制?
- 虚假唤醒是否会解锁所有等待线程,甚至是不相关的线程?
- 是否有必要获取锁并在不需要唤醒线程时通知condition_variable?
- 按回车键后输出屏幕关闭
- 要在屏幕上绘制一些小瓷砖,我应该使用 QQuickItem 还是 QQuickPaintedItem?
- SFML 向下移动时如何围绕屏幕中心旋转?
- 截取屏幕截图后程序卡住
- 如果我们使用 notify_one() 来唤醒线程,我们还需要 yield() - C++?
- C++鼠标单击时的屏幕截图不起作用
- 屏幕插入运算符<<的运算符过载问题
- 避免在条件更新时丢失唤醒是一个阻塞功能
- 获取网格中心的屏幕位置
- SFML 中的字体.信息不显示在屏幕上.显示的不是信息,而是点
- 程序性地从节能或屏幕保护中唤醒操作系统
- SDL_PollEvent导致xset dpms强制关闭后屏幕唤醒