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-09-18 23:37:21 +00:00
Родитель 2414cb7c4d
Коммит 739ab5b4ec
2 изменённых файлов: 70 добавлений и 10 удалений

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

@ -38,13 +38,40 @@
#include "nsScreenGtk.h"
#include <gdk/gdk.h>
#include <gdk/gdkx.h>
#include <gtk/gtk.h>
#include <X11/Xatom.h>
static GdkFilterReturn
root_window_event_filter(GdkXEvent *aGdkXEvent, GdkEvent *aGdkEvent,
gpointer aClosure)
{
XEvent *xevent = NS_STATIC_CAST(XEvent*, aGdkXEvent);
nsScreenGtk *ourScreen = NS_STATIC_CAST(nsScreenGtk*, aClosure);
// See comments in nsScreenGtk::Init below.
switch (xevent->type) {
case ConfigureNotify:
ourScreen->ReInit();
break;
case PropertyNotify:
{
XPropertyEvent *propertyEvent = &xevent->xproperty;
if (propertyEvent->atom == ourScreen->NetWorkareaAtom()) {
ourScreen->ReInit();
}
}
break;
default:
break;
}
return GDK_FILTER_CONTINUE;
}
nsScreenGtk :: nsScreenGtk ( )
: mScreenNum(0),
: mRootWindow(nsnull),
mScreenNum(0),
mRect(0, 0, 0, 0),
mAvailRect(0, 0, 0, 0)
{
@ -53,6 +80,11 @@ nsScreenGtk :: nsScreenGtk ( )
nsScreenGtk :: ~nsScreenGtk()
{
if (mRootWindow) {
gdk_window_remove_filter(mRootWindow, root_window_event_filter, this);
g_object_unref(mRootWindow);
mRootWindow = nsnull;
}
}
@ -106,25 +138,40 @@ nsScreenGtk :: GetColorDepth(PRInt32 *aColorDepth)
void
nsScreenGtk :: Init ()
nsScreenGtk :: Init (PRBool aReInit)
{
// We listen for configure events on the root window to pick up
// changes to this rect. We could listen for "size_changed" signals
// on the default screen to do this, except that doesn't work with
// versions of GDK predating the GdkScreen object. See bug 256646.
mAvailRect = mRect = nsRect(0, 0, gdk_screen_width(), gdk_screen_height());
// 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_STRUCTURE_MASK ==> StructureNotifyMask, for ConfigureNotify
// GDK_PROPERTY_CHANGE_MASK ==> PropertyChangeMask, for PropertyNotify
gdk_window_set_events(mRootWindow,
GdkEventMask(gdk_window_get_events(mRootWindow) |
GDK_STRUCTURE_MASK |
GDK_PROPERTY_CHANGE_MASK));
gdk_window_add_filter(mRootWindow, root_window_event_filter, this);
mNetWorkareaAtom =
XInternAtom(GDK_WINDOW_XDISPLAY(mRootWindow), "_NET_WORKAREA", False);
}
long *workareas;
GdkAtom type_returned;
@ -140,7 +187,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,
@ -166,6 +213,13 @@ nsScreenGtk :: Init ()
nsRect workarea(workareas[i], workareas[i + 1],
workareas[i + 2], workareas[i + 3]);
if (!mRect.Contains(workarea)) {
// Note that we hit this when processing screen size changes,
// since we'll get the configure event before the toolbars have
// been moved. We'll end up cleaning this up when we get the
// change notification to the _NET_WORKAREA property. However,
// we still want to listen to both, so we'll handle changes
// properly for desktop environments that don't set the
// _NET_WORKAREA property.
NS_WARNING("Invalid bounds");
continue;
}

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

@ -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,18 @@ public:
NS_DECL_ISUPPORTS
NS_DECL_NSISCREEN
void Init();
void Init(PRBool aReInit = PR_FALSE);
void ReInit() { Init(PR_TRUE); }
#ifdef MOZ_ENABLE_XINERAMA
void Init(XineramaScreenInfo *aScreenInfo);
#endif
Atom NetWorkareaAtom() { return mNetWorkareaAtom; }
private:
GdkWindow *mRootWindow;
PRUint32 mScreenNum;
Atom mNetWorkareaAtom;
nsRect mRect; // in pixels, not twips
nsRect mAvailRect; // in pixels, not twips
};