mirror of
				https://bitbucket.org/chromiumembedded/cef
				synced 2025-06-05 21:39:12 +02:00 
			
		
		
		
	Linux: Reduce resource usage when the window is minimized (issue #1369).
git-svn-id: https://chromiumembedded.googlecode.com/svn/branches/2062@1833 5089003a-bbd8-11dd-ad1f-f1f9622dbc98
This commit is contained in:
		| @@ -17,17 +17,21 @@ | ||||
|  | ||||
| namespace { | ||||
|  | ||||
| const char kAtom[] = "ATOM"; | ||||
| const char kWMDeleteWindow[] = "WM_DELETE_WINDOW"; | ||||
| const char kWMProtocols[] = "WM_PROTOCOLS"; | ||||
| const char kNetWMPing[] = "_NET_WM_PING"; | ||||
| const char kNetWMPid[] = "_NET_WM_PID"; | ||||
| const char kNetWMPing[] = "_NET_WM_PING"; | ||||
| const char kNetWMState[] = "_NET_WM_STATE"; | ||||
| const char kXdndProxy[] = "XdndProxy"; | ||||
|  | ||||
| const char* kAtomsToCache[] = { | ||||
|   kAtom, | ||||
|   kWMDeleteWindow, | ||||
|   kWMProtocols, | ||||
|   kNetWMPing, | ||||
|   kNetWMPid, | ||||
|   kNetWMPing, | ||||
|   kNetWMState, | ||||
|   kXdndProxy, | ||||
|   NULL | ||||
| }; | ||||
| @@ -360,6 +364,37 @@ uint32_t CefWindowX11::DispatchEvent(const ui::PlatformEvent& event) { | ||||
|       if (focus_pending_) | ||||
|         focus_pending_ = false; | ||||
|       break; | ||||
|     case PropertyNotify: { | ||||
|       ::Atom changed_atom = xev->xproperty.atom; | ||||
|       if (changed_atom == atom_cache_.GetAtom(kNetWMState)) { | ||||
|         // State change event like minimize/maximize. | ||||
|         if (browser_) { | ||||
|           ::Window child = FindChild(xdisplay_, xwindow_); | ||||
|           if (child) { | ||||
|             // Forward the state change to the child DesktopWindowTreeHostX11 | ||||
|             // window so that resource usage will be reduced while the window is | ||||
|             // minimized. | ||||
|             std::vector< ::Atom> atom_list; | ||||
|             if (ui::GetAtomArrayProperty(xwindow_, kNetWMState, &atom_list) && | ||||
|                 !atom_list.empty()) { | ||||
|               ui::SetAtomArrayProperty(child, kNetWMState, "ATOM", atom_list); | ||||
|             } else { | ||||
|               // Set an empty list of property values to pass the check in | ||||
|               // DesktopWindowTreeHostX11::OnWMStateUpdated(). | ||||
|               XChangeProperty(xdisplay_, | ||||
|                               child, | ||||
|                               atom_cache_.GetAtom(kNetWMState),  // name | ||||
|                               atom_cache_.GetAtom(kAtom),  // type | ||||
|                               32,  // size in bits of items in 'value' | ||||
|                               PropModeReplace, | ||||
|                               NULL, | ||||
|                               0);  // num items | ||||
|             } | ||||
|           } | ||||
|         } | ||||
|       } | ||||
|       break; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   return ui::POST_DISPATCH_STOP_PROPAGATION; | ||||
|   | ||||
| @@ -16,6 +16,7 @@ | ||||
| #include <string> | ||||
|  | ||||
| #include "cefclient/cefclient.h" | ||||
| #include "include/base/cef_scoped_ptr.h" | ||||
| #include "include/cef_app.h" | ||||
| #include "include/cef_browser.h" | ||||
| #include "include/cef_frame.h" | ||||
| @@ -115,6 +116,68 @@ gboolean WindowFocusIn(GtkWidget* widget, | ||||
|   return FALSE; | ||||
| } | ||||
|  | ||||
| gboolean WindowState(GtkWidget* widget, | ||||
|                      GdkEventWindowState* event, | ||||
|                      gpointer user_data) { | ||||
|   if (!(event->changed_mask & GDK_WINDOW_STATE_ICONIFIED)) | ||||
|     return TRUE; | ||||
|  | ||||
|   if (!g_handler) | ||||
|     return TRUE; | ||||
|   CefRefPtr<CefBrowser> browser = g_handler->GetBrowser(); | ||||
|   if (!browser) | ||||
|     return TRUE; | ||||
|  | ||||
|   const bool iconified = (event->new_window_state & GDK_WINDOW_STATE_ICONIFIED); | ||||
|   if (browser->GetHost()->IsWindowRenderingDisabled()) { | ||||
|     // Notify the off-screen browser that it was shown or hidden. | ||||
|     browser->GetHost()->WasHidden(iconified); | ||||
|   } else { | ||||
|     // Forward the state change event to the browser window. | ||||
|     ::Display* xdisplay = cef_get_xdisplay(); | ||||
|     ::Window xwindow = browser->GetHost()->GetWindowHandle(); | ||||
|  | ||||
|     // Retrieve the atoms required by the below XChangeProperty call. | ||||
|     const char* kAtoms[] = { | ||||
|       "_NET_WM_STATE", | ||||
|       "ATOM", | ||||
|       "_NET_WM_STATE_HIDDEN" | ||||
|     }; | ||||
|     Atom atoms[3]; | ||||
|     int result = XInternAtoms(xdisplay, const_cast<char**>(kAtoms), 3, false, | ||||
|                               atoms); | ||||
|     if (!result) | ||||
|       NOTREACHED(); | ||||
|  | ||||
|     if (iconified) { | ||||
|       // Set the hidden property state value. | ||||
|       scoped_ptr<Atom[]> data(new Atom[1]); | ||||
|       data[0] = atoms[2]; | ||||
|  | ||||
|       XChangeProperty(xdisplay, | ||||
|                       xwindow, | ||||
|                       atoms[0],  // name | ||||
|                       atoms[1],  // type | ||||
|                       32,  // size in bits of items in 'value' | ||||
|                       PropModeReplace, | ||||
|                       reinterpret_cast<const unsigned char*>(data.get()), | ||||
|                       1);  // num items | ||||
|     } else { | ||||
|       // Set an empty array of property state values. | ||||
|       XChangeProperty(xdisplay, | ||||
|                       xwindow, | ||||
|                       atoms[0],  // name | ||||
|                       atoms[1],  // type | ||||
|                       32,  // size in bits of items in 'value' | ||||
|                       PropModeReplace, | ||||
|                       NULL, | ||||
|                       0);  // num items | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   return TRUE; | ||||
| } | ||||
|  | ||||
| // Callback for Tests > Get Source... menu item. | ||||
| gboolean GetSourceActivated(GtkWidget* widget) { | ||||
|   if (g_handler.get() && g_handler->GetBrowserId()) | ||||
| @@ -357,6 +420,8 @@ int main(int argc, char* argv[]) { | ||||
|   gtk_window_set_default_size(GTK_WINDOW(window), 800, 600); | ||||
|   g_signal_connect(window, "focus-in-event", | ||||
|                    G_CALLBACK(WindowFocusIn), NULL); | ||||
|   g_signal_connect(window, "window-state-event",  | ||||
|                    G_CALLBACK(WindowState), NULL); | ||||
|  | ||||
|   GtkWidget* vbox = gtk_vbox_new(FALSE, 0); | ||||
|   g_signal_connect(vbox, "size-allocate", | ||||
|   | ||||
		Reference in New Issue
	
	Block a user