瀏覽代碼

smoother alt-tab handling

cxgeorge 24 年之前
父節點
當前提交
ce0972f252
共有 2 個文件被更改,包括 64 次插入31 次删除
  1. 63 31
      panda/src/wgldisplay/wglGraphicsWindow.cxx
  2. 1 0
      panda/src/wgldisplay/wglGraphicsWindow.h

+ 63 - 31
panda/src/wgldisplay/wglGraphicsWindow.cxx

@@ -49,6 +49,8 @@ TypeHandle wglGraphicsWindow::_type_handle;
 #define ERRORBOX_TITLE "Panda3D Error"
 #define ERRORBOX_TITLE "Panda3D Error"
 #define WGL_WINDOWCLASSNAME "wglDisplay"
 #define WGL_WINDOWCLASSNAME "wglDisplay"
 
 
+#define PAUSED_TIMER_ID  7   // completely arbitrary choice
+
 typedef map<HWND,wglGraphicsWindow *> HWND_PANDAWIN_MAP;
 typedef map<HWND,wglGraphicsWindow *> HWND_PANDAWIN_MAP;
 
 
 HWND_PANDAWIN_MAP hwnd_pandawin_map;
 HWND_PANDAWIN_MAP hwnd_pandawin_map;
@@ -274,6 +276,7 @@ void wglGraphicsWindow::config(void) {
     global_wglwinptr = this;  // need this until we get an HWND from CreateWindow
     global_wglwinptr = this;  // need this until we get an HWND from CreateWindow
 
 
     _exiting_window = false;
     _exiting_window = false;
+    _PandaPausedTimer = NULL;
     _mouse_input_enabled = false;
     _mouse_input_enabled = false;
     _mouse_motion_enabled = false;
     _mouse_motion_enabled = false;
     _mouse_passive_motion_enabled = false;
     _mouse_passive_motion_enabled = false;
@@ -1090,20 +1093,33 @@ handle_keyrelease(ButtonHandle key) {
   }
   }
 }
 }
 
 
-void INLINE wglGraphicsWindow::process_events(void) {
+void INLINE process_1_event(void) {
   MSG msg;
   MSG msg;
 
 
-  while(PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE)) {
-      if(!GetMessage(&msg, NULL, 0, 0)) {
-          // WM_QUIT received
-          DestroyAllWindows(false);
-          exit(msg.wParam);  // this will invoke AtExitFn
-      }
+  if(!GetMessage(&msg, NULL, 0, 0)) {
+      // WM_QUIT received
+      DestroyAllWindows(false);
+      exit(msg.wParam);  // this will invoke AtExitFn
+  }
 
 
-      // Translate virtual key messages
-      TranslateMessage(&msg);
-      // Call window_proc
-      DispatchMessage(&msg);
+  // Translate virtual key messages
+  TranslateMessage(&msg);
+  // Call window_proc
+  DispatchMessage(&msg);
+}
+
+void INLINE wglGraphicsWindow::process_events(void) {
+  if(_window_inactive) {
+      // Get 1 msg at a time until no more are left and we block and sleep,
+      // or that message changes _window_inactive status and we leave in
+      process_1_event();
+  } else {
+      MSG msg;
+
+      // handle all msgs on queue in a row
+      while(PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE)) {
+          process_1_event();
+      }
   }
   }
 }
 }
 
 
@@ -1129,30 +1145,30 @@ supports_update() const {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void wglGraphicsWindow::update(void) {
 void wglGraphicsWindow::update(void) {
 #ifdef DO_PSTATS
 #ifdef DO_PSTATS
-    if(!_window_inactive) {
-        _show_code_pcollector.stop();
-        PStatClient::main_tick();
-    }
+  _show_code_pcollector.stop();
+
+  if(!_window_inactive) {
+      PStatClient::main_tick();
+  }
 #endif
 #endif
 
 
   process_events();
   process_events();
 
 
   if(_window_inactive) {
   if(_window_inactive) {
-      Sleep( 500 );   // Dont consume CPU.
-      if(!EventQueue::get_global_event_queue()->is_queue_full())
-          throw_event("PandaPaused");   // throw panda event to invoke network-only processing
+      // note _window_inactive must be checked after process_events is called, to avoid draw_callback being called
+      if(_idle_callback)
+          call_idle_callback();
       return;
       return;
-  } else {
+  }
 
 
-      call_draw_callback(true);
+  call_draw_callback(true);
 
 
-      if(_idle_callback)
-          call_idle_callback();
+  if(_idle_callback)
+    call_idle_callback();
 
 
-    #ifdef DO_PSTATS
-        _show_code_pcollector.start();
-    #endif
-  }
+#ifdef DO_PSTATS
+  _show_code_pcollector.start();
+#endif
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -1287,7 +1303,8 @@ void wglGraphicsWindow::deactivate_window(void) {
     // current policy is to suspend minimized or deactivated fullscreen windows, but leave
     // current policy is to suspend minimized or deactivated fullscreen windows, but leave
     // regular windows running normally
     // regular windows running normally
 #ifdef _DEBUG
 #ifdef _DEBUG
-   wgldisplay_cat.spam()  << "deactivate_window called"  << endl;
+   if(wgldisplay_cat.is_spam())
+       wgldisplay_cat.spam()  << "deactivate_window called"  << endl;
 #endif
 #endif
 
 
    if((!_props._fullscreen) || _exiting_window) 
    if((!_props._fullscreen) || _exiting_window) 
@@ -1301,9 +1318,6 @@ void wglGraphicsWindow::deactivate_window(void) {
    _window_inactive = true;
    _window_inactive = true;
    unmake_current();
    unmake_current();
 
 
-   // bugbug: this isnt working right now on many drivers.  may have to
-   // destroy window and recreate a new OGL context for this to work
-
    // make sure window is minimized
    // make sure window is minimized
 
 
    WINDOWPLACEMENT wndpl;
    WINDOWPLACEMENT wndpl;
@@ -1319,6 +1333,11 @@ void wglGraphicsWindow::deactivate_window(void) {
 
 
    // revert to default display mode
    // revert to default display mode
    ChangeDisplaySettings(NULL,0x0);
    ChangeDisplaySettings(NULL,0x0);
+
+   _PandaPausedTimer = SetTimer(_mwindow,PAUSED_TIMER_ID,1500,NULL);
+   if(_PandaPausedTimer!=PAUSED_TIMER_ID) {
+       wgldisplay_cat.error() << "Error in SetTimer!\n";
+   }
 }
 }
 
 
 void wglGraphicsWindow::reactivate_window(void) {
 void wglGraphicsWindow::reactivate_window(void) {
@@ -1328,6 +1347,11 @@ void wglGraphicsWindow::reactivate_window(void) {
 
 
         _window_inactive = false;
         _window_inactive = false;
 
 
+        if(_PandaPausedTimer!=NULL) {
+            KillTimer(_mwindow,_PandaPausedTimer);
+            _PandaPausedTimer = NULL;
+        }
+
         // move window to top of zorder,
         // move window to top of zorder,
         SetWindowPos(_mwindow, HWND_TOP, 0,0,0,0, SWP_NOMOVE | SWP_NOSENDCHANGING | SWP_NOSIZE | SWP_NOOWNERZORDER);
         SetWindowPos(_mwindow, HWND_TOP, 0,0,0,0, SWP_NOMOVE | SWP_NOSENDCHANGING | SWP_NOSIZE | SWP_NOOWNERZORDER);
 
 
@@ -1373,7 +1397,7 @@ window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
           //_props._yorg = HIWORD(lparam);
           //_props._yorg = HIWORD(lparam);
           break;
           break;
 
 
-      case WM_ACTIVATE: 
+    case WM_ACTIVATE: 
             #ifdef _DEBUG
             #ifdef _DEBUG
               wgldisplay_cat.spam()  << "WM_ACTIVATE received"  << endl;
               wgldisplay_cat.spam()  << "WM_ACTIVATE received"  << endl;
             #endif
             #endif
@@ -1521,6 +1545,14 @@ window_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
                handle_mouse_entry(MOUSE_EXITED);
                handle_mouse_entry(MOUSE_EXITED);
           }
           }
           break;
           break;
+
+    case WM_TIMER:
+      if((wparam==_PandaPausedTimer) && _window_inactive) {
+         // wgldisplay_cat.spam() << "throwing PandaPaused\n";
+         throw_event("PandaPaused");   // throw panda event to invoke network-only processing
+      }
+
+      break;
   }
   }
 
 
   return DefWindowProc(hwnd, msg, wparam, lparam);
   return DefWindowProc(hwnd, msg, wparam, lparam);

+ 1 - 0
panda/src/wgldisplay/wglGraphicsWindow.h

@@ -112,6 +112,7 @@ private:
   HPALETTE          _colormap;
   HPALETTE          _colormap;
   HCURSOR           _hMouseCursor;
   HCURSOR           _hMouseCursor;
   HWND              _hOldForegroundWindow;
   HWND              _hOldForegroundWindow;
+  UINT_PTR          _PandaPausedTimer;
 
 
   DEVMODE           *_pCurrent_display_settings;
   DEVMODE           *_pCurrent_display_settings;