зеркало из https://github.com/mozilla/gecko-dev.git
Pick up dynamic changes in screen size (although some other things still cache them per-window). b=256646 r+sr=roc
This commit is contained in:
Родитель
3a863795d3
Коммит
db7bb7fe29
|
@ -38,13 +38,45 @@
|
|||
|
||||
#include "nsScreenGtk.h"
|
||||
|
||||
#include <gdk/gdk.h>
|
||||
#include <gdk/gdkx.h>
|
||||
#include <gtk/gtk.h>
|
||||
#include <X11/Xatom.h>
|
||||
|
||||
static GdkFilterReturn
|
||||
net_workarea_changed_filter(GdkXEvent *aGdkXEvent, GdkEvent *aGdkEvent,
|
||||
gpointer aClosure)
|
||||
{
|
||||
XEvent *xevent = NS_STATIC_CAST(XEvent*, aGdkXEvent);
|
||||
nsScreenGtk *ourScreen = NS_STATIC_CAST(nsScreenGtk*, aClosure);
|
||||
|
||||
switch (xevent->type) {
|
||||
case PropertyNotify:
|
||||
{
|
||||
XPropertyEvent *propertyEvent = &xevent->xproperty;
|
||||
if (propertyEvent->atom == ourScreen->NetWorkareaAtom()) {
|
||||
ourScreen->Init(PR_TRUE);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return GDK_FILTER_CONTINUE;
|
||||
}
|
||||
|
||||
static void
|
||||
screen_size_changed_cb(GdkScreen *aScreen, gpointer aClosure)
|
||||
{
|
||||
nsScreenGtk *ourScreen = NS_STATIC_CAST(nsScreenGtk*, aClosure);
|
||||
ourScreen->Init(PR_TRUE);
|
||||
}
|
||||
|
||||
|
||||
nsScreenGtk :: nsScreenGtk ( )
|
||||
: mScreenNum(0),
|
||||
: mScreen(nsnull),
|
||||
mRootWindow(nsnull),
|
||||
mScreenNum(0),
|
||||
mRect(0, 0, 0, 0),
|
||||
mAvailRect(0, 0, 0, 0)
|
||||
{
|
||||
|
@ -53,6 +85,16 @@ nsScreenGtk :: nsScreenGtk ( )
|
|||
|
||||
nsScreenGtk :: ~nsScreenGtk()
|
||||
{
|
||||
if (mRootWindow) {
|
||||
gdk_window_remove_filter(mRootWindow, net_workarea_changed_filter, this);
|
||||
g_object_unref(mRootWindow);
|
||||
mRootWindow = nsnull;
|
||||
}
|
||||
if (mScreen) {
|
||||
g_signal_handler_disconnect(G_OBJECT(mScreen), mSizeChangedHandler);
|
||||
g_object_unref(mScreen);
|
||||
mScreen = nsnull;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -106,25 +148,49 @@ nsScreenGtk :: GetColorDepth(PRInt32 *aColorDepth)
|
|||
|
||||
|
||||
void
|
||||
nsScreenGtk :: Init ()
|
||||
nsScreenGtk :: Init (PRBool aReInit)
|
||||
{
|
||||
mAvailRect = mRect = nsRect(0, 0, gdk_screen_width(), gdk_screen_height());
|
||||
if (!aReInit) {
|
||||
// Listen for "size_changed" signals on default screen to pick up
|
||||
// changes. The problem with this (event with _after) is that
|
||||
// toolbars haven't been resized yet when we get this, so instead of
|
||||
// excluding toolbars known by the window manager, we get a bunch of
|
||||
// NS_WARNING("Invalid bounds") below.
|
||||
mScreen = gdk_screen_get_default();
|
||||
g_object_ref(mScreen);
|
||||
|
||||
mSizeChangedHandler =
|
||||
g_signal_connect_after(G_OBJECT(mScreen), "size_changed",
|
||||
G_CALLBACK(screen_size_changed_cb), this);
|
||||
}
|
||||
|
||||
mAvailRect = mRect = nsRect(0, 0, gdk_screen_get_width(mScreen),
|
||||
gdk_screen_get_height(mScreen));
|
||||
|
||||
|
||||
// We need to account for the taskbar, etc in the available rect.
|
||||
// See http://freedesktop.org/Standards/wm-spec/index.html#id2767771
|
||||
|
||||
// XXX It doesn't change that often, but we should probably
|
||||
// listen for changes to _NET_WORKAREA.
|
||||
// XXX do we care about _NET_WM_STRUT_PARTIAL? That will
|
||||
// add much more complexity to the code here (our screen
|
||||
// could have a non-rectangular shape), but should
|
||||
// lead to greater accuracy.
|
||||
|
||||
if (!aReInit) {
|
||||
#if GTK_CHECK_VERSION(2,2,0)
|
||||
GdkWindow *root_window = gdk_get_default_root_window();
|
||||
mRootWindow = gdk_get_default_root_window();
|
||||
#else
|
||||
GdkWindow *root_window = GDK_ROOT_PARENT();
|
||||
mRootWindow = GDK_ROOT_PARENT();
|
||||
#endif // GTK_CHECK_VERSION(2,2,0)
|
||||
g_object_ref(mRootWindow);
|
||||
|
||||
gdk_window_set_events(mRootWindow,
|
||||
GdkEventMask(gdk_window_get_events(mRootWindow) |
|
||||
GDK_PROPERTY_CHANGE_MASK));
|
||||
gdk_window_add_filter(mRootWindow, net_workarea_changed_filter, this);
|
||||
mNetWorkareaAtom =
|
||||
XInternAtom(GDK_WINDOW_XDISPLAY(mRootWindow), "_NET_WORKAREA", False);
|
||||
}
|
||||
|
||||
long *workareas;
|
||||
GdkAtom type_returned;
|
||||
|
@ -140,7 +206,7 @@ nsScreenGtk :: Init ()
|
|||
gdk_error_trap_push();
|
||||
|
||||
// gdk_property_get uses (length + 3) / 4, hence G_MAXLONG - 3 here.
|
||||
if (!gdk_property_get(root_window,
|
||||
if (!gdk_property_get(mRootWindow,
|
||||
gdk_atom_intern ("_NET_WORKAREA", FALSE),
|
||||
cardinal_atom,
|
||||
0, G_MAXLONG - 3, FALSE,
|
||||
|
|
|
@ -40,9 +40,10 @@
|
|||
|
||||
#include "nsIScreen.h"
|
||||
#include "nsRect.h"
|
||||
#include "gdk/gdk.h"
|
||||
#include <X11/Xlib.h>
|
||||
|
||||
#ifdef MOZ_ENABLE_XINERAMA
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/extensions/Xinerama.h>
|
||||
#endif // MOZ_ENABLE_XINERAMA
|
||||
|
||||
|
@ -57,13 +58,19 @@ public:
|
|||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSISCREEN
|
||||
|
||||
void Init();
|
||||
void Init(PRBool aReInit = PR_FALSE);
|
||||
#ifdef MOZ_ENABLE_XINERAMA
|
||||
void Init(XineramaScreenInfo *aScreenInfo);
|
||||
#endif
|
||||
|
||||
Atom NetWorkareaAtom() { return mNetWorkareaAtom; }
|
||||
|
||||
private:
|
||||
GdkScreen *mScreen;
|
||||
GdkWindow *mRootWindow;
|
||||
PRUint32 mScreenNum;
|
||||
gulong mSizeChangedHandler;
|
||||
Atom mNetWorkareaAtom;
|
||||
nsRect mRect; // in pixels, not twips
|
||||
nsRect mAvailRect; // in pixels, not twips
|
||||
};
|
||||
|
|
Загрузка…
Ссылка в новой задаче