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:
dbaron%dbaron.org 2006-08-03 05:18:49 +00:00
Родитель 3a863795d3
Коммит db7bb7fe29
2 изменённых файлов: 84 добавлений и 11 удалений

Просмотреть файл

@ -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
};