application.cpp 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. #if defined(Hiro_Application)
  2. namespace hiro {
  3. auto pApplication::exit() -> void {
  4. quit();
  5. ::exit(EXIT_SUCCESS);
  6. }
  7. auto pApplication::modal() -> bool {
  8. return Application::state().modal > 0;
  9. }
  10. auto pApplication::run() -> void {
  11. if(Application::state().onMain) {
  12. while(!Application::state().quit) {
  13. Application::doMain();
  14. processEvents();
  15. }
  16. } else {
  17. QApplication::exec();
  18. }
  19. }
  20. auto pApplication::pendingEvents() -> bool {
  21. return QApplication::hasPendingEvents();
  22. }
  23. auto pApplication::processEvents() -> void {
  24. while(pendingEvents()) QApplication::processEvents();
  25. }
  26. auto pApplication::quit() -> void {
  27. QApplication::quit();
  28. qtApplication = nullptr; //note: deleting QApplication will crash libQtGui
  29. if(state().display) {
  30. if(state().screenSaverXDG && state().screenSaverWindow) {
  31. //this needs to run synchronously, so that XUnmapWindow() won't happen before xdg-screensaver is finished
  32. execute("xdg-screensaver", "resume", string{"0x", hex(state().screenSaverWindow)});
  33. XUnmapWindow(state().display, state().screenSaverWindow);
  34. state().screenSaverWindow = 0;
  35. }
  36. XCloseDisplay(state().display);
  37. state().display = nullptr;
  38. }
  39. }
  40. auto pApplication::setScreenSaver(bool screenSaver) -> void {
  41. #if defined(DISPLAY_XORG)
  42. if(state().screenSaverXDG && state().screenSaverWindow) {
  43. invoke("xdg-screensaver", screenSaver ? "resume" : "suspend", string{"0x", hex(state().screenSaverWindow)});
  44. }
  45. #endif
  46. }
  47. auto pApplication::state() -> State& {
  48. static State state;
  49. return state;
  50. }
  51. //this is sadly necessary for things like determining window frame geometry
  52. //obviously, it is used as sparingly as possible
  53. auto pApplication::synchronize() -> void {
  54. for(auto n : range(8)) {
  55. #if HIRO_QT==4 && defined(DISPLAY_XORG)
  56. QApplication::syncX();
  57. #elif HIRO_QT==5
  58. QApplication::sync();
  59. #endif
  60. Application::processEvents();
  61. usleep(2000);
  62. }
  63. }
  64. auto pApplication::initialize() -> void {
  65. #if HIRO_QT==5 && defined(PLATFORM_BSD)
  66. setenv("QTCOMPOSE", "/usr/local/lib/X11/locale/", 0);
  67. #endif
  68. #if defined(DISPLAY_XORG)
  69. state().display = XOpenDisplay(nullptr);
  70. state().screenSaverXDG = (bool)execute("xdg-screensaver", "--version").output.find("xdg-screensaver");
  71. if(state().screenSaverXDG) {
  72. auto screen = DefaultScreen(state().display);
  73. auto rootWindow = RootWindow(state().display, screen);
  74. XSetWindowAttributes attributes{};
  75. attributes.background_pixel = BlackPixel(state().display, screen);
  76. attributes.border_pixel = 0;
  77. attributes.override_redirect = true;
  78. state().screenSaverWindow = XCreateWindow(state().display, rootWindow,
  79. 0, 0, 1, 1, 0, DefaultDepth(state().display, screen),
  80. InputOutput, DefaultVisual(state().display, screen),
  81. CWBackPixel | CWBorderPixel | CWOverrideRedirect, &attributes
  82. );
  83. //note: hopefully xdg-screensaver does not require the window to be mapped ...
  84. //if it does, we're in trouble: a small 1x1 black pixel window will be visible in said case
  85. XMapWindow(state().display, state().screenSaverWindow);
  86. XFlush(state().display);
  87. }
  88. #endif
  89. static auto name = Application::state().name ? Application::state().name : string{"hiro"};
  90. //QApplication stores references to argc;
  91. //and will access them after pApplication::initialize() returns
  92. static int argc = 1;
  93. static char* argv[] = {name.get(), nullptr};
  94. static char** argvp = argv;
  95. qtApplication = new QApplication(argc, argvp);
  96. pKeyboard::initialize();
  97. }
  98. }
  99. #endif