Linux: Reduce resource usage when the window is minimized (issue #1369).
git-svn-id: https://chromiumembedded.googlecode.com/svn/trunk@1832 5089003a-bbd8-11dd-ad1f-f1f9622dbc98
This commit is contained in:
parent
fa5aa5fe4e
commit
61ffc55ec3
|
@ -17,17 +17,21 @@
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
const char kAtom[] = "ATOM";
|
||||||
const char kWMDeleteWindow[] = "WM_DELETE_WINDOW";
|
const char kWMDeleteWindow[] = "WM_DELETE_WINDOW";
|
||||||
const char kWMProtocols[] = "WM_PROTOCOLS";
|
const char kWMProtocols[] = "WM_PROTOCOLS";
|
||||||
const char kNetWMPing[] = "_NET_WM_PING";
|
|
||||||
const char kNetWMPid[] = "_NET_WM_PID";
|
const char kNetWMPid[] = "_NET_WM_PID";
|
||||||
|
const char kNetWMPing[] = "_NET_WM_PING";
|
||||||
|
const char kNetWMState[] = "_NET_WM_STATE";
|
||||||
const char kXdndProxy[] = "XdndProxy";
|
const char kXdndProxy[] = "XdndProxy";
|
||||||
|
|
||||||
const char* kAtomsToCache[] = {
|
const char* kAtomsToCache[] = {
|
||||||
|
kAtom,
|
||||||
kWMDeleteWindow,
|
kWMDeleteWindow,
|
||||||
kWMProtocols,
|
kWMProtocols,
|
||||||
kNetWMPing,
|
|
||||||
kNetWMPid,
|
kNetWMPid,
|
||||||
|
kNetWMPing,
|
||||||
|
kNetWMState,
|
||||||
kXdndProxy,
|
kXdndProxy,
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
@ -360,6 +364,37 @@ uint32_t CefWindowX11::DispatchEvent(const ui::PlatformEvent& event) {
|
||||||
if (focus_pending_)
|
if (focus_pending_)
|
||||||
focus_pending_ = false;
|
focus_pending_ = false;
|
||||||
break;
|
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;
|
return ui::POST_DISPATCH_STOP_PROPAGATION;
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "cefclient/cefclient.h"
|
#include "cefclient/cefclient.h"
|
||||||
|
#include "include/base/cef_scoped_ptr.h"
|
||||||
#include "include/cef_app.h"
|
#include "include/cef_app.h"
|
||||||
#include "include/cef_browser.h"
|
#include "include/cef_browser.h"
|
||||||
#include "include/cef_frame.h"
|
#include "include/cef_frame.h"
|
||||||
|
@ -115,6 +116,68 @@ gboolean WindowFocusIn(GtkWidget* widget,
|
||||||
return FALSE;
|
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.
|
// Callback for Tests > Get Source... menu item.
|
||||||
gboolean GetSourceActivated(GtkWidget* widget) {
|
gboolean GetSourceActivated(GtkWidget* widget) {
|
||||||
if (g_handler.get() && g_handler->GetBrowserId())
|
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);
|
gtk_window_set_default_size(GTK_WINDOW(window), 800, 600);
|
||||||
g_signal_connect(window, "focus-in-event",
|
g_signal_connect(window, "focus-in-event",
|
||||||
G_CALLBACK(WindowFocusIn), NULL);
|
G_CALLBACK(WindowFocusIn), NULL);
|
||||||
|
g_signal_connect(window, "window-state-event",
|
||||||
|
G_CALLBACK(WindowState), NULL);
|
||||||
|
|
||||||
GtkWidget* vbox = gtk_vbox_new(FALSE, 0);
|
GtkWidget* vbox = gtk_vbox_new(FALSE, 0);
|
||||||
g_signal_connect(vbox, "size-allocate",
|
g_signal_connect(vbox, "size-allocate",
|
||||||
|
|
Loading…
Reference in New Issue