Mr. Picklesworth
August 9th, 2007, 04:09 AM
I made the foolish decision to start messing with gnome-panel. What I want is an option to have panels appear behind normal windows and not set struts, thus achieving tidy desklets (very much like those of Windows Vista) under a single infrastructure. With that and some fancy applets that take advantage of the idea, it should be quite possible to have Gnome working very nicely with the informative / pretty looking desklets idea.
Unfortunately for me, this has come to involve immense pain since I have never used (or learned) xlib, and it turns out to be a horrendously complicated library to just learn on the spot.
I promise, I'll learn XLib soon!
For now, maybe someone can help me out?
I have read up on extended window manager hints (http://standards.freedesktop.org/wm-spec/wm-spec-1.3.html), which tells me that what I want is indeed possible.
I can add the _NET_WM_STATE_BELOW atom to _NET_WM_STATE, which will (should) override the default behaviour of dock windows to be always above everything else, instead making them always below normal windows, above the desktop in stacking order.
Here is a chunk of the source code from gnome-panel's panel-xutils.c:
/*
* panel-xutils.c: X related utility methods.
*
* Copyright (C) 2003 Sun Microsystems, Inc.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* Authors:
* Mark McLoughlin <mark@skynet.ie>
*/
#include "config.h"
#include "panel-xutils.h"
#include <glib.h>
#include <gdk/gdk.h>
#include <gdk/gdkx.h>
#include <X11/Xlib.h>
#include <X11/Xatom.h>
static Atom net_wm_window_type = None;
static Atom net_wm_window_type_dock = None;
static Atom net_wm_window_type_normal = None;
static Atom net_wm_strut = None;
static Atom net_wm_strut_partial = None;
void
panel_xutils_set_window_type (GdkWindow *gdk_window,
PanelXUtilsWindowType type)
{
Display *display;
Window window;
Atom atoms [2];
int i = 0;
g_return_if_fail (GDK_IS_WINDOW (gdk_window));
display = GDK_WINDOW_XDISPLAY (gdk_window);
window = GDK_WINDOW_XWINDOW (gdk_window);
if (net_wm_window_type == None)
net_wm_window_type = XInternAtom (display,
"_NET_WM_WINDOW_TYPE",
False);
switch (type) {
case PANEL_XUTILS_TYPE_DOCK:
if (net_wm_window_type_dock == None)
net_wm_window_type_dock = XInternAtom (display,
"_NET_WM_WINDOW_TYPE_DOCK",
False);
atoms [i++] = net_wm_window_type_dock;
break;
case PANEL_XUTILS_TYPE_NORMAL:
if (net_wm_window_type_normal == None)
net_wm_window_type_normal = XInternAtom (display,
"_NET_WM_WINDOW_TYPE_NORMAL",
False);
atoms [i++] = net_wm_window_type_normal;
break;
default:
g_assert_not_reached ();
break;
}
//TODO: Must set state atom: "_NET_WM_STATE_BELOW"
gdk_error_trap_push ();
XChangeProperty (display, window, net_wm_window_type,
XA_ATOM, 32, PropModeReplace,
(guchar *) &atoms, i);
gdk_error_trap_pop ();
}
In this case, type is PANEL_XUTILS_TYPE_DOCK.
As far as setting this atom is concerned, I am baffled :(
I have tried adding the following code at the end of that function:
Atom state_below;
state_below = XInternAtom (display, "_NET_WM_STATE_BELOW", False);
XChangeProperty (display, window,
XInternAtom (display,"_NET_WM_STATE",False),
XA_ATOM, 32, PropModeReplace,
(guchar *) &state_below, 1);
I have also tried putting that code in its own function called slightly later on, (called from panel_toplevel_realize).
However, it isn't giving me any change.
A bit of searching told me to use xprop, and the panel window's _NET_WM_STATE atom is unchanged:
XProp output:
_NET_WM_STATE(ATOM) = _NET_WM_STATE_SKIP_PAGER, _NET_WM_STATE_SKIP_TASKBAR
I'm a bit lost, but I would really love to have this ball rolling (and I promise I will not try to write the applets with C). Are there any xlib people among us who can help?
Unfortunately for me, this has come to involve immense pain since I have never used (or learned) xlib, and it turns out to be a horrendously complicated library to just learn on the spot.
I promise, I'll learn XLib soon!
For now, maybe someone can help me out?
I have read up on extended window manager hints (http://standards.freedesktop.org/wm-spec/wm-spec-1.3.html), which tells me that what I want is indeed possible.
I can add the _NET_WM_STATE_BELOW atom to _NET_WM_STATE, which will (should) override the default behaviour of dock windows to be always above everything else, instead making them always below normal windows, above the desktop in stacking order.
Here is a chunk of the source code from gnome-panel's panel-xutils.c:
/*
* panel-xutils.c: X related utility methods.
*
* Copyright (C) 2003 Sun Microsystems, Inc.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* Authors:
* Mark McLoughlin <mark@skynet.ie>
*/
#include "config.h"
#include "panel-xutils.h"
#include <glib.h>
#include <gdk/gdk.h>
#include <gdk/gdkx.h>
#include <X11/Xlib.h>
#include <X11/Xatom.h>
static Atom net_wm_window_type = None;
static Atom net_wm_window_type_dock = None;
static Atom net_wm_window_type_normal = None;
static Atom net_wm_strut = None;
static Atom net_wm_strut_partial = None;
void
panel_xutils_set_window_type (GdkWindow *gdk_window,
PanelXUtilsWindowType type)
{
Display *display;
Window window;
Atom atoms [2];
int i = 0;
g_return_if_fail (GDK_IS_WINDOW (gdk_window));
display = GDK_WINDOW_XDISPLAY (gdk_window);
window = GDK_WINDOW_XWINDOW (gdk_window);
if (net_wm_window_type == None)
net_wm_window_type = XInternAtom (display,
"_NET_WM_WINDOW_TYPE",
False);
switch (type) {
case PANEL_XUTILS_TYPE_DOCK:
if (net_wm_window_type_dock == None)
net_wm_window_type_dock = XInternAtom (display,
"_NET_WM_WINDOW_TYPE_DOCK",
False);
atoms [i++] = net_wm_window_type_dock;
break;
case PANEL_XUTILS_TYPE_NORMAL:
if (net_wm_window_type_normal == None)
net_wm_window_type_normal = XInternAtom (display,
"_NET_WM_WINDOW_TYPE_NORMAL",
False);
atoms [i++] = net_wm_window_type_normal;
break;
default:
g_assert_not_reached ();
break;
}
//TODO: Must set state atom: "_NET_WM_STATE_BELOW"
gdk_error_trap_push ();
XChangeProperty (display, window, net_wm_window_type,
XA_ATOM, 32, PropModeReplace,
(guchar *) &atoms, i);
gdk_error_trap_pop ();
}
In this case, type is PANEL_XUTILS_TYPE_DOCK.
As far as setting this atom is concerned, I am baffled :(
I have tried adding the following code at the end of that function:
Atom state_below;
state_below = XInternAtom (display, "_NET_WM_STATE_BELOW", False);
XChangeProperty (display, window,
XInternAtom (display,"_NET_WM_STATE",False),
XA_ATOM, 32, PropModeReplace,
(guchar *) &state_below, 1);
I have also tried putting that code in its own function called slightly later on, (called from panel_toplevel_realize).
However, it isn't giving me any change.
A bit of searching told me to use xprop, and the panel window's _NET_WM_STATE atom is unchanged:
XProp output:
_NET_WM_STATE(ATOM) = _NET_WM_STATE_SKIP_PAGER, _NET_WM_STATE_SKIP_TASKBAR
I'm a bit lost, but I would really love to have this ball rolling (and I promise I will not try to write the applets with C). Are there any xlib people among us who can help?