"show desktop button" applet
- From: Havoc Pennington <hp redhat com>
- To: desktop-devel-list gnome org
- Subject: "show desktop button" applet
- Date: 23 Sep 2002 22:10:53 -0400
Hi,
I implemented the much-requested "show desktop" button today, here are
the libwnck and panel patches. metacity needed a bugfix also before it
would work, the metacity fix is already committed.
I'll commit this soon if no one complains. As it's tiny and there's no
API involved I don't think it merits a GEP unless someone finds it
really controversial.
Havoc
Index: ChangeLog
===================================================================
RCS file: /cvs/gnome/libwnck/ChangeLog,v
retrieving revision 1.152
diff -u -p -u -r1.152 ChangeLog
--- ChangeLog 21 Sep 2002 15:54:23 -0000 1.152
+++ ChangeLog 24 Sep 2002 02:04:45 -0000
@@ -1,3 +1,28 @@
+2002-09-23 Havoc Pennington <hp pobox com>
+
+ * libwnck/test-wnck.c (main): add test stuff for showing desktop
+ feature
+
+ * libwnck/xutils.c (_wnck_toggle_showing_desktop): new function
+ (_wnck_activate_workspace): fix a hardcoded gdk_display, but it
+ looks like there are a lot more
+
+ * libwnck/screen.c (wnck_screen_toggle_showing_desktop):
+ new function
+ (wnck_screen_get_showing_desktop): new function
+
+ * libwnck/workspace-accessible.c: include headers to avoid
+ warnings
+ (wnck_workspace_accessible_get_size): add comment about how this
+ is totally broken
+
+ * libwnck/pager.c: remove some unused variables
+
+ * configure.in: version to 2.1.1 and bump current/age
+
+ * libwnck/screen.c: monitor _NET_SHOWING_DESKTOP and emit a signal
+ if it changed
+
2002-09-17 Havoc Pennington <hp redhat com>
* libwnck/window.c (update_transient_for): track a flag for
Index: configure.in
===================================================================
RCS file: /cvs/gnome/libwnck/configure.in,v
retrieving revision 1.60
diff -u -p -u -r1.60 configure.in
--- configure.in 17 Sep 2002 15:37:08 -0000 1.60
+++ configure.in 24 Sep 2002 02:04:45 -0000
@@ -2,13 +2,13 @@ AC_INIT(libwnck/window.h)
AM_CONFIG_HEADER(config.h)
-AM_INIT_AUTOMAKE(libwnck, 2.1.0)
+AM_INIT_AUTOMAKE(libwnck, 2.1.1)
AM_MAINTAINER_MODE
dnl libtool versioning for libwnck
dnl increment if the interface has additions, changes, removals.
-LIBWNCK_CURRENT=5
+LIBWNCK_CURRENT=6
dnl increment any time the source changes; set to
dnl 0 if you increment CURRENT
@@ -17,7 +17,7 @@ LIBWNCK_REVISION=0
dnl increment if any interfaces have been added; set to 0
dnl if any interfaces have been removed. removal has
dnl precedence over adding, so set to 0 if both happened.
-LIBWNCK_AGE=1
+LIBWNCK_AGE=2
AC_SUBST(LIBWNCK_CURRENT)
AC_SUBST(LIBWNCK_REVISION)
Index: libwnck/pager.c
===================================================================
RCS file: /cvs/gnome/libwnck/libwnck/pager.c,v
retrieving revision 1.27
diff -u -p -u -r1.27 pager.c
--- libwnck/pager.c 16 Sep 2002 05:42:43 -0000 1.27
+++ libwnck/pager.c 24 Sep 2002 02:04:45 -0000
@@ -1171,7 +1171,7 @@ application_opened_callback (WnckS
WnckApplication *app,
gpointer data)
{
- WnckPager *pager = WNCK_PAGER (data);
+ /* WnckPager *pager = WNCK_PAGER (data); */
}
static void
@@ -1179,7 +1179,7 @@ application_closed_callback (WnckS
WnckApplication *app,
gpointer data)
{
- WnckPager *pager = WNCK_PAGER (data);
+ /* WnckPager *pager = WNCK_PAGER (data); */
}
static void
Index: libwnck/screen.c
===================================================================
RCS file: /cvs/gnome/libwnck/libwnck/screen.c,v
retrieving revision 1.19
diff -u -p -u -r1.19 screen.c
--- libwnck/screen.c 16 Sep 2002 05:58:38 -0000 1.19
+++ libwnck/screen.c 24 Sep 2002 02:04:45 -0000
@@ -52,6 +52,8 @@ struct _WnckScreenPrivate
Pixmap bg_pixmap;
guint update_handler;
+
+ guint showing_desktop : 1;
/* if you add flags, be sure to set them
* when we create the screen so we get an initial update
@@ -62,6 +64,7 @@ struct _WnckScreenPrivate
guint need_update_active_window : 1;
guint need_update_workspace_names : 1;
guint need_update_bg_pixmap : 1;
+ guint need_update_showing_desktop : 1;
};
enum {
@@ -75,6 +78,7 @@ enum {
APPLICATION_OPENED,
APPLICATION_CLOSED,
BACKGROUND_CHANGED,
+ SHOWING_DESKTOP_CHANGED,
LAST_SIGNAL
};
@@ -87,6 +91,7 @@ static void update_workspace_list (Wnc
static void update_active_workspace (WnckScreen *screen);
static void update_active_window (WnckScreen *screen);
static void update_workspace_names (WnckScreen *screen);
+static void update_showing_desktop (WnckScreen *screen);
static void queue_update (WnckScreen *screen);
static void unqueue_update (WnckScreen *screen);
@@ -108,6 +113,7 @@ static void emit_application_opened
static void emit_application_closed (WnckScreen *screen,
WnckApplication *app);
static void emit_background_changed (WnckScreen *screen);
+static void emit_showing_desktop_changed (WnckScreen *screen);
static gpointer parent_class;
static guint signals[LAST_SIGNAL] = { 0 };
@@ -249,6 +255,19 @@ wnck_screen_class_init (WnckScreenClass
NULL, NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0);
+ signals[SHOWING_DESKTOP_CHANGED] =
+ g_signal_new ("showing_desktop_changed",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST,
+#if 0
+ /* FIXME when we can break ABI add this */
+ G_STRUCT_OFFSET (WnckScreenClass, showing_desktop_changed),
+#else
+ 0,
+#endif
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
}
static void
@@ -298,6 +317,7 @@ wnck_screen_construct (WnckScreen *scree
screen->priv->need_update_active_window = TRUE;
screen->priv->need_update_workspace_names = TRUE;
screen->priv->need_update_bg_pixmap = TRUE;
+ screen->priv->need_update_showing_desktop = TRUE;
queue_update (screen);
}
@@ -568,6 +588,12 @@ _wnck_screen_process_property_notify (Wn
screen->priv->need_update_bg_pixmap = TRUE;
queue_update (screen);
}
+ else if (xevent->xproperty.atom ==
+ _wnck_atom_get ("_NET_SHOWING_DESKTOP"))
+ {
+ screen->priv->need_update_showing_desktop = TRUE;
+ queue_update (screen);
+ }
}
static gboolean
@@ -1149,6 +1175,26 @@ update_bg_pixmap (WnckScreen *screen)
}
static void
+update_showing_desktop (WnckScreen *screen)
+{
+ int showing_desktop;
+
+ if (!screen->priv->need_update_showing_desktop)
+ return;
+
+ screen->priv->need_update_showing_desktop = FALSE;
+
+ showing_desktop = FALSE;
+ _wnck_get_cardinal (screen->priv->xroot,
+ _wnck_atom_get ("_NET_SHOWING_DESKTOP"),
+ &showing_desktop);
+
+ screen->priv->showing_desktop = showing_desktop != 0;
+
+ emit_showing_desktop_changed (screen);
+}
+
+static void
do_update_now (WnckScreen *screen)
{
if (screen->priv->update_handler)
@@ -1165,7 +1211,8 @@ do_update_now (WnckScreen *screen)
update_active_workspace (screen);
update_active_window (screen);
update_workspace_names (screen);
-
+ update_showing_desktop (screen);
+
update_bg_pixmap (screen);
}
@@ -1288,6 +1335,14 @@ emit_background_changed (WnckScreen *scr
0);
}
+static void
+emit_showing_desktop_changed (WnckScreen *screen)
+{
+ g_signal_emit (G_OBJECT (screen),
+ signals[SHOWING_DESKTOP_CHANGED],
+ 0);
+}
+
gboolean
wnck_screen_net_wm_supports (WnckScreen *screen,
const char *atom)
@@ -1353,4 +1408,22 @@ wnck_screen_release_workspace_layout (Wn
_wnck_release_desktop_layout_manager (screen->priv->xscreen,
current_token);
+}
+
+gboolean
+wnck_screen_get_showing_desktop (WnckScreen *screen)
+{
+ g_return_val_if_fail (WNCK_IS_SCREEN (screen), FALSE);
+
+ return screen->priv->showing_desktop;
+}
+
+void
+wnck_screen_toggle_showing_desktop (WnckScreen *screen,
+ gboolean show)
+{
+ g_return_if_fail (WNCK_IS_SCREEN (screen));
+
+ _wnck_toggle_showing_desktop (screen->priv->xscreen,
+ show);
}
Index: libwnck/screen.h
===================================================================
RCS file: /cvs/gnome/libwnck/libwnck/screen.h,v
retrieving revision 1.10
diff -u -p -u -r1.10 screen.h
--- libwnck/screen.h 16 May 2002 04:11:47 -0000 1.10
+++ libwnck/screen.h 24 Sep 2002 02:04:45 -0000
@@ -82,6 +82,22 @@ struct _WnckScreenClass
/* New background */
void (* background_changed) (WnckScreen *screen);
+
+#if 0
+ /* FIXME uncomment all this next time we feel like breaking ABI */
+
+ /* Toggle showing desktop */
+ void (* showing_desktop_changed) (WnckScreen *screen);
+
+ void (* pad1) (void);
+ void (* pad2) (void);
+ void (* pad3) (void);
+ void (* pad4) (void);
+ void (* pad5) (void);
+ void (* pad6) (void);
+ void (* pad7) (void);
+ void (* pad8) (void);
+#endif
};
GType wnck_screen_get_type (void) G_GNUC_CONST;
@@ -109,6 +125,10 @@ gulong wnck_screen_get_background_pixmap
int wnck_screen_get_width (WnckScreen *screen);
int wnck_screen_get_height (WnckScreen *screen);
+
+gboolean wnck_screen_get_showing_desktop (WnckScreen *screen);
+void wnck_screen_toggle_showing_desktop (WnckScreen *screen,
+ gboolean show);
int wnck_screen_try_set_workspace_layout (WnckScreen *screen,
int current_token,
Index: libwnck/test-wnck.c
===================================================================
RCS file: /cvs/gnome/libwnck/libwnck/test-wnck.c,v
retrieving revision 1.11
diff -u -p -u -r1.11 test-wnck.c
--- libwnck/test-wnck.c 24 Oct 2001 23:14:18 -0000 1.11
+++ libwnck/test-wnck.c 24 Sep 2002 02:04:45 -0000
@@ -28,6 +28,8 @@ static void application_opened_callback
WnckApplication *app);
static void application_closed_callback (WnckScreen *screen,
WnckApplication *app);
+static void showing_desktop_changed_callback (WnckScreen *screen,
+ gpointer data);
static void window_name_changed_callback (WnckWindow *window,
gpointer data);
static void window_state_changed_callback (WnckWindow *window,
@@ -87,7 +89,10 @@ main (int argc, char **argv)
g_signal_connect (G_OBJECT (screen), "application_closed",
G_CALLBACK (application_closed_callback),
NULL);
-
+ g_signal_connect (G_OBJECT (screen), "showing_desktop_changed",
+ G_CALLBACK (showing_desktop_changed_callback),
+ NULL);
+
global_tree_model = create_tree_model ();
global_tree_view = create_tree_view ();
@@ -219,6 +224,14 @@ application_closed_callback (WnckScreen
{
g_print ("Application closed\n");
queue_refill_model ();
+}
+
+static void
+showing_desktop_changed_callback (WnckScreen *screen,
+ gpointer data)
+{
+ g_print ("Showing desktop now = %d\n",
+ wnck_screen_get_showing_desktop (screen));
}
static void
Index: libwnck/workspace-accessible.c
===================================================================
RCS file: /cvs/gnome/libwnck/libwnck/workspace-accessible.c,v
retrieving revision 1.2
diff -u -p -u -r1.2 workspace-accessible.c
--- libwnck/workspace-accessible.c 21 Aug 2002 06:57:32 -0000 1.2
+++ libwnck/workspace-accessible.c 24 Sep 2002 02:04:45 -0000
@@ -23,7 +23,7 @@
#include <errno.h>
#include <unistd.h>
#include "workspace-accessible.h"
-
+#include "private.h"
static void wnck_workspace_accessible_class_init (WnckWorkspaceAccessibleClass *klass);
static const char* wnck_workspace_accessible_get_name (AtkObject *obj);
static const char* wnck_workspace_accessible_get_description (AtkObject *obj);
@@ -150,6 +150,8 @@ wnck_workspace_accessible_get_size (AtkC
AtkCoordType coords;
int x, y;
+ /* FIXME this is blatantly broken (coords uninitialized) */
+
wnck_workspace_accessible_get_extents (component, &x, &y, width, height, coords);
}
Index: libwnck/xutils.c
===================================================================
RCS file: /cvs/gnome/libwnck/libwnck/xutils.c,v
retrieving revision 1.30
diff -u -p -u -r1.30 xutils.c
--- libwnck/xutils.c 7 Aug 2002 05:01:02 -0000 1.30
+++ libwnck/xutils.c 24 Sep 2002 02:04:45 -0000
@@ -959,6 +959,30 @@ _wnck_activate_workspace (Screen *screen
&xev);
}
+void
+_wnck_toggle_showing_desktop (Screen *screen,
+ gboolean show)
+{
+ XEvent xev;
+
+ xev.xclient.type = ClientMessage;
+ xev.xclient.serial = 0;
+ xev.xclient.send_event = True;
+ xev.xclient.display = DisplayOfScreen (screen);
+ xev.xclient.window = RootWindowOfScreen (screen);
+ xev.xclient.message_type = _wnck_atom_get ("_NET_SHOWING_DESKTOP");
+ xev.xclient.format = 32;
+ xev.xclient.data.l[0] = show != FALSE;
+ xev.xclient.data.l[1] = 0;
+ xev.xclient.data.l[2] = 0;
+
+ XSendEvent (DisplayOfScreen (screen),
+ RootWindowOfScreen (screen),
+ False,
+ SubstructureRedirectMask | SubstructureNotifyMask,
+ &xev);
+}
+
Window
_wnck_get_group_leader (Window xwindow)
{
Index: libwnck/xutils.h
===================================================================
RCS file: /cvs/gnome/libwnck/libwnck/xutils.h,v
retrieving revision 1.18
diff -u -p -u -r1.18 xutils.h
--- libwnck/xutils.h 7 Aug 2002 05:01:02 -0000 1.18
+++ libwnck/xutils.h 24 Sep 2002 02:04:45 -0000
@@ -110,6 +110,9 @@ void _wnck_keyboard_move (Screen *s
void _wnck_keyboard_size (Screen *screen,
Window xwindow);
+void _wnck_toggle_showing_desktop (Screen *screen,
+ gboolean show);
+
typedef struct _WnckIconCache WnckIconCache;
WnckIconCache *_wnck_icon_cache_new (void);
Index: ChangeLog
===================================================================
RCS file: /cvs/gnome/gnome-panel/ChangeLog,v
retrieving revision 1.475
diff -u -p -u -r1.475 ChangeLog
--- ChangeLog 20 Sep 2002 06:17:48 -0000 1.475
+++ ChangeLog 24 Sep 2002 02:04:57 -0000
@@ -1,3 +1,7 @@
+2002-09-23 Havoc Pennington <hp pobox com>
+
+ * configure.in: require a newer libwnck
+
2002-09-20 James Willcox <jwillcox gnome org>
* configure.in: Look for gtk-2.1, and define HAVE_GTK_MULTIHEAD for
Index: configure.in
===================================================================
RCS file: /cvs/gnome/gnome-panel/configure.in,v
retrieving revision 1.423
diff -u -p -u -r1.423 configure.in
--- configure.in 20 Sep 2002 06:17:48 -0000 1.423
+++ configure.in 24 Sep 2002 02:04:57 -0000
@@ -39,7 +39,7 @@ LIBGNOME_REQUIRED=2.0.0
LIBGNOMEUI_REQUIRED=2.0.0
ORBIT_REQUIRED=2.4.0
GNOME_VFS_MODULE_REQUIRED=1.9.16
-LIBWNCK_REQUIRED=2.1.0
+LIBWNCK_REQUIRED=2.1.1
AC_SUBST(GTK_REQUIRED)
AC_SUBST(GDK_PIXBUF_REQUIRED)
Index: applets/gen_util/ChangeLog
===================================================================
RCS file: /cvs/gnome/gnome-panel/applets/gen_util/ChangeLog,v
retrieving revision 1.422
diff -u -p -u -r1.422 ChangeLog
--- applets/gen_util/ChangeLog 16 Sep 2002 07:14:45 -0000 1.422
+++ applets/gen_util/ChangeLog 24 Sep 2002 02:04:57 -0000
@@ -1,3 +1,11 @@
+2002-09-23 Havoc Pennington <hp redhat com>
+
+ * clock.c (destroy_clock): free the timeformat string
+
+ * showdesktop.c: show desktop applet
+
+ * GNOME_GenUtilApplet_Factory.server.in.in: add ShowDesktopApplet
+
2002-09-16 Mark McLoughlin <mark skynet ie>
* Makefile.am, multihead-hacks.h: kill
Index: applets/gen_util/GNOME_GenUtilApplet_Factory.server.in.in
===================================================================
RCS file: /cvs/gnome/gnome-panel/applets/gen_util/GNOME_GenUtilApplet_Factory.server.in.in,v
retrieving revision 1.17
diff -u -p -u -r1.17 GNOME_GenUtilApplet_Factory.server.in.in
--- applets/gen_util/GNOME_GenUtilApplet_Factory.server.in.in 5 Mar 2002 10:55:12 -0000 1.17
+++ applets/gen_util/GNOME_GenUtilApplet_Factory.server.in.in 24 Sep 2002 02:04:57 -0000
@@ -75,4 +75,21 @@
<oaf_attribute name="panel:category" type="string" _value="Internet"/>
</oaf_server>
+
+<oaf_server iid="OAFIID:GNOME_ShowDesktopApplet"
+ type="factory"
+ location="OAFIID:GNOME_GenUtilApplet_Factory">
+
+ <oaf_attribute name="repo_ids" type="stringv">
+ <item value="IDL:GNOME/Vertigo/PanelAppletShell:1.0"/>
+ <item value="IDL:Bonobo/Control:1.0"/>
+ <item value="IDL:Bonobo/Unknown:1.0"/>
+ </oaf_attribute>
+ <oaf_attribute name="name" type="string" _value="Show Desktop Button"/>
+ <oaf_attribute name="description" type="string" _value="Button to hide application windows and show the desktop"/>
+ <oaf_attribute name="panel:icon" type="string" value="gnome-show-desktop.png"/>
+ <oaf_attribute name="panel:category" type="string" _value="Utility"/>
+
+</oaf_server>
+
</oaf_info>
Index: applets/gen_util/GNOME_ShowDesktopApplet.xml
===================================================================
RCS file: applets/gen_util/GNOME_ShowDesktopApplet.xml
diff -N applets/gen_util/GNOME_ShowDesktopApplet.xml
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ applets/gen_util/GNOME_ShowDesktopApplet.xml 24 Sep 2002 02:04:57 -0000
@@ -0,0 +1,10 @@
+<Root>
+ <popups>
+ <popup name="button3">
+ <menuitem name="Show Desktop Help Item" verb="ShowDesktopHelp" _label="_Help"
+ pixtype="stock" pixname="gtk-help"/>
+ <menuitem name="Show Desktop About Item" verb="ShowDesktopAbout" _label="_About..."
+ pixtype="stock" pixname="gnome-stock-about"/>
+ </popup>
+ </popups>
+</Root>
Index: applets/gen_util/Makefile.am
===================================================================
RCS file: /cvs/gnome/gnome-panel/applets/gen_util/Makefile.am,v
retrieving revision 1.57
diff -u -p -u -r1.57 Makefile.am
--- applets/gen_util/Makefile.am 16 Sep 2002 07:14:45 -0000 1.57
+++ applets/gen_util/Makefile.am 24 Sep 2002 02:04:57 -0000
@@ -26,6 +26,10 @@ DISABLE_DEPRECATED_CFLAGS = \
gladedir = $(datadir)/gen_util
glade_DATA = pager.glade tasklist.glade
+pixmapdir = $(datadir)/pixmaps
+pixmap_DATA = \
+ gnome-show-desktop.png
+
EGGFILES = \
egg-screen-exec.h \
egg-screen-exec.c \
@@ -40,6 +44,8 @@ libgen_util_applet_2_la_SOURCES = \
clock.h \
pager.c \
pager.h \
+ showdesktop.c \
+ showdesktop.h \
tasklist.c \
tasklist.h \
mailcheck.c \
@@ -79,7 +85,8 @@ ui_DATA = \
GNOME_ClockApplet.xml \
GNOME_MailCheckApplet.xml \
GNOME_PagerApplet.xml \
- GNOME_TasklistApplet.xml
+ GNOME_ShowDesktopApplet.xml \
+ GNOME_TasklistApplet.xml
serverdir = $(libdir)/bonobo/servers
server_in_files = GNOME_GenUtilApplet_Factory.server.in
@@ -110,6 +117,7 @@ EXTRA_DIST = GNOME_GenUtilApplet_Factory
$(soundlist_in_files) \
$(schemas_in_files) \
$(glade_DATA) \
+ $(pixmap_DATA) \
$(ui_DATA)
EGGDIR = $(srcdir)/../../../libegg/libegg/screen-exec
Index: applets/gen_util/clock.c
===================================================================
RCS file: /cvs/gnome/gnome-panel/applets/gen_util/clock.c,v
retrieving revision 1.84
diff -u -p -u -r1.84 clock.c
--- applets/gen_util/clock.c 16 Sep 2002 07:14:45 -0000 1.84
+++ applets/gen_util/clock.c 24 Sep 2002 02:04:57 -0000
@@ -367,6 +367,8 @@ destroy_clock(GtkWidget * widget, ClockD
cd->props = NULL;
}
+ g_free (cd->timeformat);
+
g_free (cd);
}
Index: applets/gen_util/gnome-show-desktop.png
===================================================================
RCS file: applets/gen_util/gnome-show-desktop.png
diff -N applets/gen_util/gnome-show-desktop.png
Binary files /dev/null and gnome-show-desktop.png differ
Index: applets/gen_util/main.c
===================================================================
RCS file: /cvs/gnome/gnome-panel/applets/gen_util/main.c,v
retrieving revision 1.19
diff -u -p -u -r1.19 main.c
--- applets/gen_util/main.c 4 Mar 2002 17:53:40 -0000 1.19
+++ applets/gen_util/main.c 24 Sep 2002 02:04:57 -0000
@@ -28,6 +28,7 @@
#include "mailcheck.h"
#include "clock.h"
#include "pager.h"
+#include "showdesktop.h"
#include "tasklist.h"
static gboolean
@@ -49,6 +50,9 @@ genutil_factory (PanelApplet *applet,
if (!strcmp (iid, "OAFIID:GNOME_MailcheckApplet"))
retval = fill_mailcheck_applet(applet);
+ if (!strcmp (iid, "OAFIID:GNOME_ShowDesktopApplet"))
+ retval = fill_show_desktop_applet(applet);
+
return retval;
}
Index: applets/gen_util/showdesktop.c
===================================================================
RCS file: applets/gen_util/showdesktop.c
diff -N applets/gen_util/showdesktop.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ applets/gen_util/showdesktop.c 24 Sep 2002 02:04:57 -0000
@@ -0,0 +1,493 @@
+/* "Show desktop" panel applet */
+
+/*
+ * Copyright (C) 2002 Red Hat, Inc.
+ * Developed by Havoc Pennington
+ *
+ * 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.
+ */
+
+#include <config.h>
+#include "showdesktop.h"
+#include <gtk/gtktogglebutton.h>
+#include <gtk/gtktooltips.h>
+#include <gtk/gtkimage.h>
+#include <gtk/gtkstock.h>
+#include <gtk/gtkmessagedialog.h>
+#include <libgnome/libgnome.h>
+#include <libgnomeui/gnome-about.h>
+#define WNCK_I_KNOW_THIS_IS_UNSTABLE
+#include <libwnck/screen.h>
+#include "egg-screen-help.h"
+
+#include <string.h>
+
+typedef struct {
+ /* widgets */
+ GtkWidget *applet;
+ GtkWidget *button;
+ GtkWidget *image;
+ GdkPixbuf *icon;
+
+ PanelAppletOrient orient;
+ int size;
+
+ WnckScreen *wnck_screen;
+
+ guint showing_desktop : 1;
+} ShowDesktopData;
+
+static void display_help_dialog (BonoboUIComponent *uic,
+ ShowDesktopData *sdd,
+ const gchar *verbname);
+static void display_about_dialog (BonoboUIComponent *uic,
+ ShowDesktopData *sdd,
+ const gchar *verbname);
+
+static void update_icon (ShowDesktopData *sdd);
+static void update_button_state (ShowDesktopData *sdd);
+static void update_button_display (ShowDesktopData *sdd);
+
+static void button_toggled_callback (GtkWidget *button,
+ ShowDesktopData *sdd);
+static void show_desktop_changed_callback (WnckScreen *screen,
+ ShowDesktopData *sdd);
+
+static void
+set_tooltip (GtkWidget *widget,
+ const char *tip)
+{
+ GtkTooltips *tooltips;
+
+ tooltips = g_object_get_data (G_OBJECT (widget), "tooltips");
+ if (!tooltips) {
+ tooltips = gtk_tooltips_new ();
+ g_object_ref (tooltips);
+ gtk_object_sink (GTK_OBJECT (tooltips));
+ g_object_set_data_full (G_OBJECT (widget), "tooltips", tooltips,
+ (GDestroyNotify) g_object_unref);
+ }
+
+ gtk_tooltips_set_tip (tooltips, widget, tip, NULL);
+}
+
+/* this is when the panel orientation changes */
+
+static void
+applet_change_orient (PanelApplet *applet,
+ PanelAppletOrient orient,
+ ShowDesktopData *sdd)
+{
+ GtkOrientation new_orient;
+
+ switch (orient)
+ {
+ case PANEL_APPLET_ORIENT_LEFT:
+ case PANEL_APPLET_ORIENT_RIGHT:
+ new_orient = GTK_ORIENTATION_VERTICAL;
+ break;
+ case PANEL_APPLET_ORIENT_UP:
+ case PANEL_APPLET_ORIENT_DOWN:
+ default:
+ new_orient = GTK_ORIENTATION_HORIZONTAL;
+ break;
+ }
+
+ if (new_orient == sdd->orient)
+ return;
+
+ sdd->orient = new_orient;
+
+ update_icon (sdd);
+}
+
+static void
+applet_change_background (PanelApplet *applet,
+ PanelAppletBackgroundType type,
+ GdkColor *color,
+ const gchar *pixmap,
+ ShowDesktopData *sdd)
+{
+ if (type == PANEL_NO_BACKGROUND) {
+ GtkRcStyle *rc_style;
+
+ rc_style = gtk_rc_style_new ();
+
+ gtk_widget_modify_style (sdd->applet, rc_style);
+
+ g_object_unref (rc_style);
+
+ } else if (type == PANEL_COLOR_BACKGROUND)
+ gtk_widget_modify_bg (sdd->applet, GTK_STATE_NORMAL, color);
+
+ /* else if (type == PANEL_PIXMAP_BACKGROUND)
+ * FIXME: Handle this when the panel support works again
+ */
+}
+
+
+/* this is when the panel size changes */
+static void
+applet_change_pixel_size (PanelApplet *applet,
+ gint size,
+ ShowDesktopData *sdd)
+{
+ if (sdd->size == size)
+ return;
+
+ sdd->size = size;
+
+ update_icon (sdd);
+}
+
+static void
+update_icon (ShowDesktopData *sdd)
+{
+ int width, height;
+ GdkPixbuf *scaled;
+ double aspect;
+ int icon_size;
+
+ if (sdd->icon == NULL)
+ return;
+
+ width = gdk_pixbuf_get_width (sdd->icon);
+ height = gdk_pixbuf_get_height (sdd->icon);
+
+ aspect = (double) width / (double) height;
+
+#define SPACE_FOR_BUTTON_BORDER 3
+ icon_size = sdd->size - SPACE_FOR_BUTTON_BORDER;
+
+ scaled = NULL;
+
+ /* Make it fit on the given panel */
+ switch (sdd->orient) {
+ case GTK_ORIENTATION_HORIZONTAL:
+ width = icon_size * aspect;
+ height = icon_size;
+ break;
+ case GTK_ORIENTATION_VERTICAL:
+ height = icon_size / aspect;
+ width = icon_size;
+ break;
+ }
+
+ scaled = gdk_pixbuf_scale_simple (sdd->icon,
+ width, height,
+ GDK_INTERP_BILINEAR);
+
+ if (scaled == NULL)
+ return;
+
+ gtk_image_set_from_pixbuf (GTK_IMAGE (sdd->image),
+ scaled);
+
+ g_object_unref (G_OBJECT (scaled));
+}
+
+static const BonoboUIVerb show_desktop_menu_verbs [] = {
+ BONOBO_UI_UNSAFE_VERB ("ShowDesktopHelp", display_help_dialog),
+ BONOBO_UI_UNSAFE_VERB ("ShowDesktopAbout", display_about_dialog),
+ BONOBO_UI_VERB_END
+};
+
+/* This updates things that should be consistent with the button's appearance,
+ * and update_button_state updates the button appearance itself
+ */
+static void
+update_button_display (ShowDesktopData *sdd)
+{
+ if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (sdd->button))) {
+ set_tooltip (sdd->button,
+ _("Click here to restore hidden windows."));
+ } else {
+ set_tooltip (sdd->button,
+ _("Click here to hide all windows and show the desktop."));
+ }
+}
+
+static void
+update_button_state (ShowDesktopData *sdd)
+{
+ if (sdd->showing_desktop) {
+ g_signal_handlers_block_by_func (G_OBJECT (sdd->button),
+ G_CALLBACK (button_toggled_callback),
+ sdd);
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (sdd->button),
+ TRUE);
+ g_signal_handlers_unblock_by_func (G_OBJECT (sdd->button),
+ G_CALLBACK (button_toggled_callback),
+ sdd);
+ } else {
+ g_signal_handlers_block_by_func (G_OBJECT (sdd->button),
+ G_CALLBACK (button_toggled_callback),
+ sdd);
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (sdd->button),
+ FALSE);
+ g_signal_handlers_unblock_by_func (G_OBJECT (sdd->button),
+ G_CALLBACK (button_toggled_callback),
+ sdd);
+ }
+
+ update_button_display (sdd);
+}
+
+static void
+applet_destroyed (GtkWidget *applet,
+ ShowDesktopData *sdd)
+{
+ g_object_unref (G_OBJECT (sdd->icon));
+
+ g_free (sdd);
+}
+
+static gboolean
+do_not_eat_button_press (GtkWidget *widget,
+ GdkEventButton *event)
+{
+ if (event->button != 1) {
+ g_signal_stop_emission_by_name (widget, "button_press_event");
+ }
+
+ return FALSE;
+}
+
+gboolean
+fill_show_desktop_applet (PanelApplet *applet)
+{
+ ShowDesktopData *sdd;
+ char *file;
+ GError *error;
+
+ sdd = g_new0 (ShowDesktopData, 1);
+
+ sdd->applet = GTK_WIDGET (applet);
+
+ file = gnome_program_locate_file (NULL, GNOME_FILE_DOMAIN_PIXMAP,
+ "gnome-show-desktop.png", TRUE, NULL);
+ error = NULL;
+ if (file) {
+ sdd->icon = gdk_pixbuf_new_from_file (file, &error);
+ g_free (file);
+ }
+
+ if (sdd->icon == NULL) {
+ g_printerr (_("Failed to load %s: %s\n"),
+ file, error ? error->message : _("File not found"));
+ if (error)
+ g_error_free (error);
+ }
+
+ if (sdd->icon) {
+ sdd->image = gtk_image_new_from_pixbuf (sdd->icon);
+ } else {
+ sdd->image = gtk_image_new_from_stock (GTK_STOCK_MISSING_IMAGE,
+ GTK_ICON_SIZE_SMALL_TOOLBAR);
+ }
+
+ switch (panel_applet_get_orient (applet)) {
+ case PANEL_APPLET_ORIENT_LEFT:
+ case PANEL_APPLET_ORIENT_RIGHT:
+ sdd->orient = GTK_ORIENTATION_VERTICAL;
+ break;
+ case PANEL_APPLET_ORIENT_UP:
+ case PANEL_APPLET_ORIENT_DOWN:
+ default:
+ sdd->orient = GTK_ORIENTATION_HORIZONTAL;
+ break;
+ }
+
+ sdd->size = panel_applet_get_size (PANEL_APPLET (sdd->applet));
+
+ update_icon (sdd);
+
+ sdd->button = gtk_toggle_button_new ();
+
+ g_signal_connect (G_OBJECT (sdd->button), "button_press_event",
+ G_CALLBACK (do_not_eat_button_press), NULL);
+
+ g_signal_connect (G_OBJECT (sdd->button), "toggled",
+ G_CALLBACK (button_toggled_callback), sdd);
+
+ gtk_container_set_border_width (GTK_CONTAINER (sdd->button), 1);
+ gtk_container_add (GTK_CONTAINER (sdd->button), sdd->image);
+ gtk_container_add (GTK_CONTAINER (sdd->applet), sdd->button);
+
+ update_button_state (sdd);
+
+ sdd->wnck_screen =
+ wnck_screen_get (gdk_screen_get_number (gtk_widget_get_screen (sdd->applet)));
+
+ if (sdd->wnck_screen != NULL)
+ g_signal_connect (G_OBJECT (sdd->wnck_screen),
+ "showing_desktop_changed",
+ G_CALLBACK (show_desktop_changed_callback),
+ sdd);
+ else
+ g_warning ("Could not get WnckScreen!");
+
+ /* FIXME: Update this comment. */
+ /* we have to bind change_orient before we do applet_widget_add
+ since we need to get an initial change_orient signal to set our
+ initial oriantation, and we get that during the _add call */
+ g_signal_connect (G_OBJECT (sdd->applet),
+ "change_orient",
+ G_CALLBACK (applet_change_orient),
+ sdd);
+
+ /* similiar to the above in semantics*/
+ g_signal_connect (G_OBJECT (sdd->applet),
+ "change_size",
+ G_CALLBACK (applet_change_pixel_size),
+ sdd);
+
+ /* FIXME: initial background, this needs some panel-applet voodoo */
+ g_signal_connect (G_OBJECT (sdd->applet),
+ "change_background",
+ G_CALLBACK (applet_change_background),
+ sdd);
+
+ panel_applet_setup_menu_from_file (PANEL_APPLET (sdd->applet),
+ NULL,
+ "GNOME_ShowDesktopApplet.xml",
+ NULL,
+ show_desktop_menu_verbs,
+ sdd);
+
+ g_signal_connect (G_OBJECT (sdd->applet),
+ "destroy",
+ G_CALLBACK (applet_destroyed),
+ sdd);
+
+ gtk_widget_show_all (sdd->applet);
+
+ return TRUE;
+}
+
+static void
+display_help_dialog (BonoboUIComponent *uic,
+ ShowDesktopData *sdd,
+ const gchar *verbname)
+{
+ GError *error = NULL;
+ static GnomeProgram *applet_program = NULL;
+
+ if (!applet_program) {
+ /* FIXME there is no way this crack is right; it's some junk
+ * copied from clock.c
+ */
+ int argc = 1;
+ char *argv[2] = { "show-desktop" };
+ applet_program = gnome_program_init ("show-desktop", VERSION,
+ LIBGNOME_MODULE, argc, argv,
+ GNOME_PROGRAM_STANDARD_PROPERTIES, NULL);
+ }
+
+ egg_screen_help_display_desktop (
+ gtk_widget_get_screen (sdd->applet),
+ applet_program, "show-desktop", "show-desktop",
+ NULL, &error);
+
+ if (error) {
+ GtkWidget *dialog;
+ dialog = gtk_message_dialog_new (NULL,
+ GTK_DIALOG_MODAL,
+ GTK_MESSAGE_ERROR,
+ GTK_BUTTONS_CLOSE,
+ _("There was an error displaying help: %s"),
+ error->message);
+
+ g_signal_connect (G_OBJECT (dialog), "response",
+ G_CALLBACK (gtk_widget_destroy),
+ NULL);
+
+ gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE);
+ gtk_window_set_screen (GTK_WINDOW (dialog),
+ gtk_widget_get_screen (sdd->applet));
+ gtk_widget_show (dialog);
+ g_error_free (error);
+ }
+}
+
+static void
+display_about_dialog (BonoboUIComponent *uic,
+ ShowDesktopData *sdd,
+ const gchar *verbname)
+{
+ static GtkWidget *about = NULL;
+
+ static const gchar *authors[] =
+ {
+ "Havoc Pennington <hp redhat com>",
+ NULL
+ };
+ static const char *documenters[] =
+ {
+ NULL
+ };
+
+ /* Translator credits */
+ const char *translator_credits = _("translator_credits");
+
+ if (about) {
+ gtk_window_set_screen (GTK_WINDOW (about),
+ gtk_widget_get_screen (sdd->applet));
+ gtk_window_present (GTK_WINDOW (about));
+ return;
+ }
+
+ about = gnome_about_new (_("Show Desktop Button"), VERSION,
+ _("(C) 2002 Red Hat, Inc."),
+ _("This button lets you hide all windows and show the desktop"),
+ authors,
+ documenters,
+ strcmp (translator_credits, "translator_credits") != 0 ? translator_credits : NULL,
+ sdd->icon);
+
+ gtk_window_set_wmclass (GTK_WINDOW (about), "show-desktop", "show-desktop");
+ gtk_window_set_screen (GTK_WINDOW (about),
+ gtk_widget_get_screen (sdd->applet));
+
+ if (sdd->icon)
+ gtk_window_set_icon (GTK_WINDOW (about), sdd->icon);
+
+ g_signal_connect (G_OBJECT(about), "destroy",
+ (GCallback)gtk_widget_destroyed, &about);
+
+ gtk_widget_show (about);
+}
+
+static void
+button_toggled_callback (GtkWidget *button,
+ ShowDesktopData *sdd)
+{
+ if (sdd->wnck_screen != NULL)
+ wnck_screen_toggle_showing_desktop (sdd->wnck_screen,
+ gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button)));
+
+ update_button_display (sdd);
+}
+
+static void
+show_desktop_changed_callback (WnckScreen *screen,
+ ShowDesktopData *sdd)
+{
+ if (sdd->wnck_screen != NULL)
+ sdd->showing_desktop =
+ wnck_screen_get_showing_desktop (sdd->wnck_screen);
+ update_button_state (sdd);
+}
Index: applets/gen_util/showdesktop.h
===================================================================
RCS file: applets/gen_util/showdesktop.h
diff -N applets/gen_util/showdesktop.h
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ applets/gen_util/showdesktop.h 24 Sep 2002 02:04:57 -0000
@@ -0,0 +1,37 @@
+/* "Show desktop" panel applet */
+
+/*
+ * Copyright (C) 2002 Red Hat, Inc.
+ * Developed by Havoc Pennington
+ *
+ * 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.
+ */
+
+#ifndef _SHOWDESKTOP_H_
+#define _SHOWDESKTOP_H_
+
+#include <glib/gmacros.h>
+#include <panel-applet.h>
+
+G_BEGIN_DECLS
+
+gboolean fill_show_desktop_applet (PanelApplet *applet);
+
+G_END_DECLS
+
+#endif
+
+
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]