Added an applet to embed series of applications (and associated launcher)

This commit is contained in:
Pierre Pronchery 2012-10-05 23:57:29 +00:00
parent dfcb6eb9d7
commit fbaf8011e1
8 changed files with 385 additions and 7 deletions

View File

@ -69,7 +69,8 @@ typedef struct _PanelAppletDefinition
typedef enum _PanelMessage
{
PANEL_MESSAGE_SHOW = 0
PANEL_MESSAGE_SHOW = 0,
PANEL_MESSAGE_EMBED
} PanelMessage;
typedef enum _PanelMessageShow

View File

@ -1,4 +1,4 @@
TARGETS = battery.so bluetooth.so clock.so close.so cpu.so cpufreq.so desktop.so gps.so gsm.so keyboard.so lock.so logout.so main.so memory.so mixer.so pager.so phone.so rotate.so separator.so spacer.so swap.so systray.so tasks.so template.so title.so usb.so volume.so wpa_supplicant.so
TARGETS = battery.so bluetooth.so clock.so close.so cpu.so cpufreq.so desktop.so embed.so gps.so gsm.so keyboard.so lock.so logout.so main.so memory.so mixer.so pager.so phone.so rotate.so separator.so spacer.so swap.so systray.so tasks.so template.so title.so usb.so volume.so wpa_supplicant.so
PREFIX = /usr/local
DESTDIR =
LIBDIR = $(PREFIX)/lib
@ -68,6 +68,13 @@ desktop_LDFLAGS = $(LDFLAGSF) $(LDFLAGS) `pkg-config --libs x11`
desktop.so: $(desktop_OBJS)
$(CCSHARED) -o desktop.so $(desktop_OBJS) $(desktop_LDFLAGS)
embed_OBJS = embed.o
embed_CFLAGS = $(CPPFLAGSF) $(CPPFLAGS) $(CFLAGSF) $(CFLAGS)
embed_LDFLAGS = $(LDFLAGSF) $(LDFLAGS)
embed.so: $(embed_OBJS)
$(CCSHARED) -o embed.so $(embed_OBJS) $(embed_LDFLAGS)
gps_OBJS = gps.o
gps_CFLAGS = $(CPPFLAGSF) $(CPPFLAGS) $(CFLAGSF) $(CFLAGS)
gps_LDFLAGS = $(LDFLAGSF) $(LDFLAGS)
@ -236,6 +243,9 @@ cpufreq.o: cpufreq.c ../../include/Panel.h
desktop.o: desktop.c ../../include/Panel.h
$(CC) $(desktop_CFLAGS) -c desktop.c
embed.o: embed.c ../../include/Panel.h
$(CC) $(embed_CFLAGS) -c embed.c
gps.o: gps.c ../../include/Panel.h
$(CC) $(gps_CFLAGS) -c gps.c
@ -300,7 +310,7 @@ wpa_supplicant.o: wpa_supplicant.c ../../include/Panel.h
$(CC) $(wpa_supplicant_CFLAGS) -c wpa_supplicant.c
clean:
$(RM) -- $(battery_OBJS) $(bluetooth_OBJS) $(clock_OBJS) $(close_OBJS) $(cpu_OBJS) $(cpufreq_OBJS) $(desktop_OBJS) $(gps_OBJS) $(gsm_OBJS) $(keyboard_OBJS) $(lock_OBJS) $(logout_OBJS) $(main_OBJS) $(memory_OBJS) $(mixer_OBJS) $(pager_OBJS) $(phone_OBJS) $(rotate_OBJS) $(separator_OBJS) $(spacer_OBJS) $(swap_OBJS) $(systray_OBJS) $(tasks_OBJS) $(template_OBJS) $(title_OBJS) $(usb_OBJS) $(volume_OBJS) $(wpa_supplicant_OBJS)
$(RM) -- $(battery_OBJS) $(bluetooth_OBJS) $(clock_OBJS) $(close_OBJS) $(cpu_OBJS) $(cpufreq_OBJS) $(desktop_OBJS) $(embed_OBJS) $(gps_OBJS) $(gsm_OBJS) $(keyboard_OBJS) $(lock_OBJS) $(logout_OBJS) $(main_OBJS) $(memory_OBJS) $(mixer_OBJS) $(pager_OBJS) $(phone_OBJS) $(rotate_OBJS) $(separator_OBJS) $(spacer_OBJS) $(swap_OBJS) $(systray_OBJS) $(tasks_OBJS) $(template_OBJS) $(title_OBJS) $(usb_OBJS) $(volume_OBJS) $(wpa_supplicant_OBJS)
distclean: clean
$(RM) -- $(TARGETS)
@ -321,6 +331,8 @@ install: $(TARGETS)
$(MKDIR) $(DESTDIR)$(LIBDIR)/Panel/applets
$(INSTALL) -m 0644 -- desktop.so $(DESTDIR)$(LIBDIR)/Panel/applets/desktop.so
$(MKDIR) $(DESTDIR)$(LIBDIR)/Panel/applets
$(INSTALL) -m 0644 -- embed.so $(DESTDIR)$(LIBDIR)/Panel/applets/embed.so
$(MKDIR) $(DESTDIR)$(LIBDIR)/Panel/applets
$(INSTALL) -m 0644 -- gps.so $(DESTDIR)$(LIBDIR)/Panel/applets/gps.so
$(MKDIR) $(DESTDIR)$(LIBDIR)/Panel/applets
$(INSTALL) -m 0644 -- gsm.so $(DESTDIR)$(LIBDIR)/Panel/applets/gsm.so
@ -369,6 +381,7 @@ uninstall:
$(RM) -- $(DESTDIR)$(LIBDIR)/Panel/applets/cpu.so
$(RM) -- $(DESTDIR)$(LIBDIR)/Panel/applets/cpufreq.so
$(RM) -- $(DESTDIR)$(LIBDIR)/Panel/applets/desktop.so
$(RM) -- $(DESTDIR)$(LIBDIR)/Panel/applets/embed.so
$(RM) -- $(DESTDIR)$(LIBDIR)/Panel/applets/gps.so
$(RM) -- $(DESTDIR)$(LIBDIR)/Panel/applets/gsm.so
$(RM) -- $(DESTDIR)$(LIBDIR)/Panel/applets/keyboard.so

177
src/applets/embed.c Normal file
View File

@ -0,0 +1,177 @@
/* $Id$ */
/* Copyright (c) 2012 Pierre Pronchery <khorben@defora.org> */
/* This file is part of DeforaOS Desktop Panel */
/* 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, version 3 of the License.
*
* 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, see <http://www.gnu.org/licenses/>. */
#ifdef DEBUG
# include <stdio.h>
#endif
#include <System.h>
#include <Desktop.h>
#include "Panel.h"
/* Embed */
/* private */
/* types */
typedef struct _PanelApplet
{
PanelAppletHelper * helper;
guint source;
/* widgets */
GtkWidget * button;
GtkWidget * window;
GtkWidget * vbox;
} Embed;
/* prototypes */
static Embed * _embed_init(PanelAppletHelper * helper,
GtkWidget ** widget);
static void _embed_destroy(Embed * embed);
/* callbacks */
static int _embed_on_desktop_message(void * data, uint32_t value1,
uint32_t value2, uint32_t value3);
static int _embed_on_idle(gpointer data);
static void _embed_on_toggled(GtkWidget * widget, gpointer data);
/* public */
/* variables */
PanelAppletDefinition applet =
{
"Embed",
"gnome-window-manager",
NULL,
_embed_init,
_embed_destroy,
NULL,
FALSE,
TRUE
};
/* private */
/* functions */
/* embed_init */
static Embed * _embed_init(PanelAppletHelper * helper,
GtkWidget ** widget)
{
Embed * embed;
GtkWidget * image;
if((embed = object_new(sizeof(*embed))) == NULL)
{
helper->error(NULL, error_get(), 1);
return NULL;
}
embed->helper = helper;
embed->source = 0;
embed->window = NULL;
embed->vbox = NULL;
embed->button = gtk_toggle_button_new();
#if GTK_CHECK_VERSION(2, 12, 0)
gtk_widget_set_tooltip_text(embed->button, "Show embedded widgets");
#endif
gtk_button_set_relief(GTK_BUTTON(embed->button), GTK_RELIEF_NONE);
g_signal_connect(G_OBJECT(embed->button), "toggled", G_CALLBACK(
_embed_on_toggled), embed);
image = gtk_image_new_from_icon_name(applet.icon, helper->icon_size);
gtk_container_add(GTK_CONTAINER(embed->button), image);
gtk_widget_show_all(embed->button);
*widget = embed->button;
g_idle_add(_embed_on_idle, embed);
return embed;
}
/* embed_destroy */
static void _embed_destroy(Embed * embed)
{
if(embed->source != 0)
g_source_remove(embed->source);
object_delete(embed);
}
/* callbacks */
/* embed_on_desktop_message */
static int _embed_on_desktop_message(void * data, uint32_t value1,
uint32_t value2, uint32_t value3)
{
Embed * embed = data;
GtkWidget * socket;
#ifdef DEBUG
fprintf(stderr, "DEBUG: %s(%u, %u, %u)\n", __func__, value1, value2,
value3);
#endif
if(value1 != PANEL_MESSAGE_EMBED)
return 0;
socket = gtk_socket_new();
gtk_box_pack_start(GTK_BOX(embed->vbox), socket, FALSE, TRUE, 0);
gtk_widget_show(socket);
gtk_socket_add_id(GTK_SOCKET(socket), value2);
return 0;
}
/* embed_on_idle */
static int _embed_on_idle(gpointer data)
{
Embed * embed = data;
embed->source = 0;
embed->window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_accept_focus(GTK_WINDOW(embed->window), FALSE);
#if GTK_CHECK_VERSION(2, 6, 0)
gtk_window_set_focus_on_map(GTK_WINDOW(embed->window), FALSE);
#endif
/* XXX let this be configurable (resize applications automatically) */
gtk_window_set_type_hint(GTK_WINDOW(embed->window),
GDK_WINDOW_TYPE_HINT_DOCK);
embed->vbox = gtk_vbox_new(FALSE, 0);
gtk_container_add(GTK_CONTAINER(embed->window), embed->vbox);
gtk_widget_show(embed->vbox);
desktop_message_register(PANEL_CLIENT_MESSAGE,
_embed_on_desktop_message, embed);
return FALSE;
}
/* embed_on_toggled */
static void _embed_on_toggled(GtkWidget * widget, gpointer data)
{
Embed * embed = data;
PanelAppletHelper * helper = embed->helper;
gint x = 0;
gint y = 0;
gboolean push_in;
if(embed->window == NULL)
_embed_on_idle(embed);
if(embed->window == NULL)
return;
helper->position_menu(helper->panel, (GtkMenu *)embed->window, &x, &y,
&push_in);
gtk_window_move(GTK_WINDOW(embed->window), x, y);
if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)))
gtk_widget_show(embed->window);
else
gtk_widget_hide(embed->window);
}

View File

@ -1,4 +1,4 @@
targets=battery,bluetooth,clock,close,cpu,cpufreq,desktop,gps,gsm,keyboard,lock,logout,main,memory,mixer,pager,phone,rotate,separator,spacer,swap,systray,tasks,template,title,usb,volume,wpa_supplicant
targets=battery,bluetooth,clock,close,cpu,cpufreq,desktop,embed,gps,gsm,keyboard,lock,logout,main,memory,mixer,pager,phone,rotate,separator,spacer,swap,systray,tasks,template,title,usb,volume,wpa_supplicant
cppflags_force=-I ../../include
#cppflags=-D EMBEDDED
cflags_force=-W `pkg-config --cflags libSystem gtk+-2.0` -fPIC
@ -66,6 +66,14 @@ install=$(LIBDIR)/Panel/applets
[desktop.c]
depends=../../include/Panel.h
[embed]
type=plugin
sources=embed.c
install=$(LIBDIR)/Panel/applets
[embed.c]
depends=../../include/Panel.h
[gps]
type=plugin
sources=gps.c

View File

@ -418,6 +418,9 @@ static int _new_on_message(void * data, uint32_t value1, uint32_t value2,
if(what & PANEL_MESSAGE_SHOW_SETTINGS)
panel_show_preferences(panel, show);
break;
case PANEL_MESSAGE_EMBED:
/* ignore it (not meant to be handled here) */
break;
}
return 0;
}

View File

@ -1,4 +1,4 @@
TARGETS = panel-notify panel-test
TARGETS = panel-embed panel-notify panel-test
PREFIX = /usr/local
DESTDIR =
BINDIR = $(PREFIX)/bin
@ -16,6 +16,13 @@ INSTALL ?= install
all: $(TARGETS)
panel-embed_OBJS = embed.o
panel-embed_CFLAGS = $(CPPFLAGSF) $(CPPFLAGS) $(CFLAGSF) $(CFLAGS)
panel-embed_LDFLAGS = $(LDFLAGSF) $(LDFLAGS)
panel-embed: $(panel-embed_OBJS)
$(CC) -o panel-embed $(panel-embed_OBJS) $(panel-embed_LDFLAGS)
panel-notify_OBJS = notify.o
panel-notify_CFLAGS = $(CPPFLAGSF) $(CPPFLAGS) -D PREFIX=\"$(PREFIX)\" $(CFLAGSF) $(CFLAGS)
panel-notify_LDFLAGS = $(LDFLAGSF) $(LDFLAGS)
@ -30,6 +37,9 @@ panel-test_LDFLAGS = $(LDFLAGSF) $(LDFLAGS)
panel-test: $(panel-test_OBJS)
$(CC) -o panel-test $(panel-test_OBJS) $(panel-test_LDFLAGS)
embed.o: embed.c ../include/Panel.h ../config.h
$(CC) $(panel-embed_CFLAGS) -c embed.c
notify.o: notify.c helper.c ../src/panel.h ../config.h
$(CC) $(panel-notify_CFLAGS) -c notify.c
@ -37,16 +47,19 @@ test.o: test.c helper.c ../src/panel.h ../config.h
$(CC) $(panel-test_CFLAGS) -c test.c
clean:
$(RM) -- $(panel-notify_OBJS) $(panel-test_OBJS)
$(RM) -- $(panel-embed_OBJS) $(panel-notify_OBJS) $(panel-test_OBJS)
distclean: clean
$(RM) -- $(TARGETS)
install: $(TARGETS)
$(MKDIR) $(DESTDIR)$(BINDIR)
$(INSTALL) -m 0755 -- panel-embed $(DESTDIR)$(BINDIR)/panel-embed
$(MKDIR) $(DESTDIR)$(BINDIR)
$(INSTALL) -m 0755 -- panel-notify $(DESTDIR)$(BINDIR)/panel-notify
uninstall:
$(RM) -- $(DESTDIR)$(BINDIR)/panel-embed
$(RM) -- $(DESTDIR)$(BINDIR)/panel-notify
.PHONY: all clean distclean install uninstall

155
tools/embed.c Normal file
View File

@ -0,0 +1,155 @@
/* $Id$ */
/* Copyright (c) 2012 Pierre Pronchery <khorben@defora.org> */
/* This file is part of DeforaOS Desktop Panel */
/* 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, version 3 of the License.
*
* 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, see <http://www.gnu.org/licenses/>. */
#define DEBUG
#include <sys/wait.h>
#include <stdio.h>
#include <stdlib.h>
#include <Desktop.h>
#include "../include/Panel.h"
/* private */
/* prototypes */
static int _embed(int argc, char * argv[]);
/* callbacks */
static gboolean _embed_on_can_read(GIOChannel * channel, GIOCondition condition,
gpointer data);
static void _embed_on_child(GPid pid, gint status, gpointer data);
static int _error(char const * message, int ret);
static int _usage(void);
/* functions */
/* embed */
static int _embed(int argc, char * argv[])
{
GSpawnFlags flags = G_SPAWN_SEARCH_PATH | G_SPAWN_CHILD_INHERITS_STDIN
| G_SPAWN_DO_NOT_REAP_CHILD;
GPid pid;
int fd;
GError * error = NULL;
GIOChannel * channel;
if(g_spawn_async_with_pipes(NULL, argv, NULL, flags, NULL, NULL, &pid,
NULL, &fd, NULL, &error) == FALSE)
{
_error(error->message, 1);
g_error_free(error);
return -1;
}
g_child_watch_add(pid, _embed_on_child, NULL);
channel = g_io_channel_unix_new(fd);
g_io_channel_set_encoding(channel, NULL, NULL);
g_io_add_watch(channel, G_IO_IN, _embed_on_can_read, NULL);
gtk_main();
g_io_channel_unref(channel);
return 0;
}
/* callbacks */
/* embed_on_can_read */
static gboolean _embed_on_can_read(GIOChannel * channel, GIOCondition condition,
gpointer data)
{
gchar * str;
gsize length;
GError * error = NULL;
GIOStatus status;
uint32_t xid;
char * p;
status = g_io_channel_read_line(channel, &str, &length, NULL, &error);
switch(status)
{
case G_IO_STATUS_ERROR:
_error(error->message, 1);
g_error_free(error);
break;
case G_IO_STATUS_NORMAL:
case G_IO_STATUS_EOF:
if(length == 0 || str == NULL)
break;
xid = strtoul(str, &p, 10);
g_free(str);
if(str[0] == '\0' || *p != '\n')
{
_error("Could not obtain the XID", 1);
break;
}
#ifdef DEBUG
fprintf(stderr, "DEBUG: %s() %u\n", __func__, xid);
#endif
desktop_message_send(PANEL_CLIENT_MESSAGE,
PANEL_MESSAGE_EMBED, xid, 0);
return FALSE;
case G_IO_STATUS_AGAIN:
break;
}
gtk_main_quit();
return FALSE;
}
/* embed_on_child */
static void _embed_on_child(GPid pid, gint status, gpointer data)
{
if(WIFEXITED(status) || WIFSIGNALED(status))
{
g_spawn_close_pid(pid);
gtk_main_quit();
}
}
/* error */
static int _error(char const * message, int ret)
{
fprintf(stderr, "%s%s\n", "panel-embed: ", message);
return ret;
}
/* usage */
static int _usage(void)
{
fputs("Usage: panel-embed command [arguments...]\n", stderr);
return 1;
}
/* public */
/* functions */
/* main */
int main(int argc, char * argv[])
{
int o;
gtk_init(&argc, &argv);
while((o = getopt(argc, argv, "")) != -1)
switch(o)
{
default:
return _usage();
}
if(optind == argc)
return _usage();
return (_embed(argc - optind, &argv[optind]) == 0) ? 0 : 2;
}

View File

@ -1,9 +1,14 @@
targets=panel-notify,panel-test
targets=panel-embed,panel-notify,panel-test
cflags_force=-W `pkg-config --cflags libSystem libDesktop`
cflags=-Wall -g -O2
ldflags_force=`pkg-config --libs libSystem libDesktop`
dist=Makefile,helper.c
[panel-embed]
type=binary
sources=embed.c
install=$(BINDIR)
[panel-notify]
type=binary
cppflags=-D PREFIX=\"$(PREFIX)\"
@ -15,6 +20,9 @@ type=binary
cppflags=-D PREFIX=\"$(PREFIX)\"
sources=test.c
[embed.c]
depends=../include/Panel.h,../config.h
[notify.c]
depends=helper.c,../src/panel.h,../config.h