You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1006 lines
30 KiB
1006 lines
30 KiB
/* vim: set expandtab ts=8 sw=4: */
|
|
|
|
/* $Id$
|
|
*
|
|
* Copyright © 2005 Jasper Huijsmans <jasper@xfce.org>
|
|
*
|
|
* 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 Library 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.
|
|
*/
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
#include <config.h>
|
|
#endif
|
|
|
|
#include <string.h>
|
|
#include <time.h>
|
|
#include <gtk/gtk.h>
|
|
|
|
#include <libxfcegui4/libxfcegui4.h>
|
|
#include <libxfce4panel/xfce-panel-window.h>
|
|
#include <libxfce4panel/xfce-itembar.h>
|
|
#include <libxfce4panel/xfce-panel-item-iface.h>
|
|
|
|
#include <libxfce4panel/xfce-panel-enum-types.h>
|
|
|
|
#include "panel.h"
|
|
#include "panel-app.h"
|
|
#include "panel-properties.h"
|
|
#include "panel-item-manager.h"
|
|
#include "panel-dnd.h"
|
|
|
|
/* PanelPrivate struct */
|
|
#include "panel-private.h"
|
|
|
|
#ifndef _
|
|
#define _(x) x
|
|
#endif
|
|
|
|
enum
|
|
{
|
|
PROP_0,
|
|
PROP_SIZE,
|
|
PROP_MONITOR,
|
|
PROP_SCREEN_POSITION,
|
|
PROP_XOFFSET,
|
|
PROP_YOFFSET,
|
|
PROP_AUTOHIDE,
|
|
PROP_FULL_WIDTH,
|
|
PROP_TRANSPARENCY,
|
|
PROP_ACTIVE_TRANS
|
|
};
|
|
|
|
|
|
/* GObject */
|
|
static void panel_finalize (GObject * object);
|
|
|
|
static void panel_get_property (GObject * object,
|
|
guint prop_id,
|
|
GValue * value,
|
|
GParamSpec * pspec);
|
|
|
|
static void panel_set_property (GObject * object,
|
|
guint prop_id,
|
|
const GValue * value,
|
|
GParamSpec * pspec);
|
|
|
|
/* GtkWidget */
|
|
static void panel_size_request (GtkWidget * widget,
|
|
GtkRequisition * requisition);
|
|
|
|
static gboolean panel_button_pressed (GtkWidget *widget,
|
|
GdkEventButton *ev);
|
|
|
|
/* plugin menu */
|
|
static void panel_menu_deactivated (Panel *panel);
|
|
|
|
static void panel_menu_opened (Panel *panel);
|
|
|
|
/* DND dest */
|
|
static void _panel_drag_data_received (GtkWidget *widget,
|
|
GdkDragContext *context,
|
|
gint x,
|
|
gint y,
|
|
GtkSelectionData *data,
|
|
guint info,
|
|
guint time,
|
|
Panel *panel);
|
|
|
|
static gboolean _panel_drag_drop (GtkWidget *widget,
|
|
GdkDragContext *context,
|
|
gint x,
|
|
gint y,
|
|
guint time,
|
|
Panel *panel);
|
|
|
|
/* DND source */
|
|
static void _panel_drag_begin (GtkWidget *widget,
|
|
GdkDragContext *drag_context,
|
|
Panel *panel);
|
|
|
|
static void _panel_drag_end (GtkWidget *widget,
|
|
GdkDragContext *drag_context,
|
|
Panel *panel);
|
|
|
|
static void _panel_drag_data_get (GtkWidget *widget,
|
|
GdkDragContext *drag_context,
|
|
GtkSelectionData *data,
|
|
guint info,
|
|
guint time,
|
|
Panel *panel);
|
|
|
|
static void _panel_drag_data_delete (GtkWidget *widget,
|
|
GdkDragContext *drag_context,
|
|
Panel *panel);
|
|
|
|
/* pass through button press events */
|
|
static gboolean _panel_itembar_button_pressed (GtkWidget *widget,
|
|
GdkEventButton *ev,
|
|
Panel *panel);
|
|
|
|
/* menu */
|
|
static GtkWidget *_panel_create_menu (Panel *panel);
|
|
|
|
|
|
/* this sets up a lot of stuff, see GObject API reference */
|
|
G_DEFINE_TYPE (Panel, panel, XFCE_TYPE_PANEL_WINDOW);
|
|
|
|
static void
|
|
panel_class_init (PanelClass * klass)
|
|
{
|
|
GObjectClass *object_class;
|
|
GtkWidgetClass *widget_class;
|
|
GParamSpec *pspec;
|
|
|
|
g_type_class_add_private (klass, sizeof (PanelPrivate));
|
|
|
|
object_class = (GObjectClass *) klass;
|
|
widget_class = (GtkWidgetClass *) klass;
|
|
|
|
object_class->finalize = panel_finalize;
|
|
object_class->get_property = panel_get_property;
|
|
object_class->set_property = panel_set_property;
|
|
|
|
widget_class->button_press_event = panel_button_pressed;
|
|
widget_class->size_request = panel_size_request;
|
|
|
|
/* properties */
|
|
|
|
pspec = g_param_spec_int ("size",
|
|
"Size",
|
|
"The size of the panel",
|
|
MIN_SIZE, MAX_SIZE,
|
|
DEFAULT_SIZE, G_PARAM_READWRITE);
|
|
|
|
g_object_class_install_property (object_class, PROP_SIZE, pspec);
|
|
|
|
pspec = g_param_spec_int ("monitor",
|
|
"Monitor",
|
|
"The monitor number of the panel",
|
|
0, G_MAXINT,
|
|
DEFAULT_MONITOR, G_PARAM_READWRITE);
|
|
|
|
g_object_class_install_property (object_class, PROP_MONITOR, pspec);
|
|
|
|
pspec = g_param_spec_enum ("screen-position",
|
|
"Screen position",
|
|
"The screen position of the panel",
|
|
XFCE_TYPE_SCREEN_POSITION,
|
|
DEFAULT_SCREEN_POSITION, G_PARAM_READWRITE);
|
|
|
|
g_object_class_install_property (object_class, PROP_SCREEN_POSITION,
|
|
pspec);
|
|
|
|
pspec = g_param_spec_int ("xoffset",
|
|
"Offset in x direction",
|
|
"Offset in x direction",
|
|
0, G_MAXINT,
|
|
DEFAULT_XOFFSET, G_PARAM_READWRITE);
|
|
|
|
g_object_class_install_property (object_class, PROP_XOFFSET, pspec);
|
|
|
|
pspec = g_param_spec_int ("yoffset",
|
|
"Offset in y direction",
|
|
"Offset in y direction",
|
|
0, G_MAXINT,
|
|
DEFAULT_YOFFSET, G_PARAM_READWRITE);
|
|
|
|
g_object_class_install_property (object_class, PROP_YOFFSET, pspec);
|
|
|
|
pspec = g_param_spec_boolean ("autohide",
|
|
"panel_autohide",
|
|
"Automatically hide the panel",
|
|
DEFAULT_AUTOHIDE, G_PARAM_READWRITE);
|
|
|
|
g_object_class_install_property (object_class, PROP_AUTOHIDE, pspec);
|
|
|
|
pspec = g_param_spec_int ("fullwidth",
|
|
"panel_fullwidth",
|
|
"Use the full screen width",
|
|
XFCE_PANEL_NORMAL_WIDTH,
|
|
XFCE_PANEL_SPAN_MONITORS,
|
|
DEFAULT_FULL_WIDTH, G_PARAM_READWRITE);
|
|
|
|
g_object_class_install_property (object_class, PROP_FULL_WIDTH, pspec);
|
|
|
|
pspec = g_param_spec_int ("transparency",
|
|
"panel_transparency",
|
|
"Transparency of the panel",
|
|
0, 100,
|
|
DEFAULT_TRANSPARENCY, G_PARAM_READWRITE);
|
|
|
|
g_object_class_install_property (object_class, PROP_TRANSPARENCY, pspec);
|
|
|
|
pspec = g_param_spec_boolean ("activetrans",
|
|
"panel_activetrans",
|
|
"Keep the active panel transparent",
|
|
DEFAULT_ACTIVE_TRANS, G_PARAM_READWRITE);
|
|
|
|
g_object_class_install_property (object_class, PROP_ACTIVE_TRANS, pspec);
|
|
}
|
|
|
|
static void
|
|
panel_init (Panel * panel)
|
|
{
|
|
PanelPrivate *priv;
|
|
|
|
priv = panel->priv = PANEL_GET_PRIVATE (panel);
|
|
|
|
priv->size = DEFAULT_SIZE;
|
|
priv->monitor = DEFAULT_MONITOR;
|
|
priv->screen_position = DEFAULT_SCREEN_POSITION;
|
|
priv->xoffset = DEFAULT_XOFFSET;
|
|
priv->yoffset = DEFAULT_YOFFSET;
|
|
priv->autohide = DEFAULT_AUTOHIDE;
|
|
priv->full_width = DEFAULT_FULL_WIDTH;
|
|
priv->transparency = DEFAULT_TRANSPARENCY;
|
|
priv->activetrans = DEFAULT_ACTIVE_TRANS;
|
|
|
|
gtk_window_set_title (GTK_WINDOW (panel), "Xfce Panel");
|
|
|
|
priv->itembar = xfce_itembar_new (GTK_ORIENTATION_HORIZONTAL);
|
|
gtk_widget_show (priv->itembar);
|
|
gtk_container_add (GTK_CONTAINER (panel), priv->itembar);
|
|
|
|
/* DND */
|
|
g_signal_connect (priv->itembar, "drag-data-received",
|
|
G_CALLBACK (_panel_drag_data_received), panel);
|
|
|
|
g_signal_connect (priv->itembar, "drag-drop",
|
|
G_CALLBACK (_panel_drag_drop), panel);
|
|
|
|
g_signal_connect (priv->itembar, "drag-begin",
|
|
G_CALLBACK (_panel_drag_begin), panel);
|
|
|
|
g_signal_connect (priv->itembar, "drag-end",
|
|
G_CALLBACK (_panel_drag_end), panel);
|
|
|
|
g_signal_connect (priv->itembar, "drag-data-get",
|
|
G_CALLBACK (_panel_drag_data_get), panel);
|
|
|
|
g_signal_connect (priv->itembar, "drag-data-delete",
|
|
G_CALLBACK (_panel_drag_data_delete), panel);
|
|
|
|
/* mouse click */
|
|
g_signal_connect (priv->itembar, "button-press-event",
|
|
G_CALLBACK (_panel_itembar_button_pressed), panel);
|
|
|
|
/* menu */
|
|
priv->menu = _panel_create_menu (PANEL (panel));
|
|
|
|
priv->opacity = priv->saved_opacity = 0;
|
|
}
|
|
|
|
static void
|
|
panel_finalize (GObject * object)
|
|
{
|
|
/* TODO: properly ref and unref private widgets */
|
|
|
|
G_OBJECT_CLASS (panel_parent_class)->finalize (object);
|
|
}
|
|
|
|
static void
|
|
panel_get_property (GObject * object, guint prop_id,
|
|
GValue * value, GParamSpec * pspec)
|
|
{
|
|
PanelPrivate *priv = PANEL(object)->priv;
|
|
|
|
switch (prop_id)
|
|
{
|
|
case PROP_SIZE:
|
|
g_value_set_int (value, priv->size);
|
|
break;
|
|
case PROP_MONITOR:
|
|
g_value_set_int (value, priv->monitor);
|
|
break;
|
|
case PROP_SCREEN_POSITION:
|
|
g_value_set_enum (value, priv->screen_position);
|
|
break;
|
|
case PROP_XOFFSET:
|
|
g_value_set_int (value, priv->xoffset);
|
|
break;
|
|
case PROP_YOFFSET:
|
|
g_value_set_int (value, priv->yoffset);
|
|
break;
|
|
case PROP_AUTOHIDE:
|
|
g_value_set_boolean (value, priv->autohide);
|
|
break;
|
|
case PROP_FULL_WIDTH:
|
|
g_value_set_int (value, priv->full_width);
|
|
break;
|
|
case PROP_TRANSPARENCY:
|
|
g_value_set_int (value, priv->transparency);
|
|
break;
|
|
case PROP_ACTIVE_TRANS:
|
|
g_value_set_boolean (value, priv->activetrans);
|
|
break;
|
|
default:
|
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
|
break;
|
|
}
|
|
}
|
|
|
|
static void
|
|
panel_set_property (GObject * object, guint prop_id,
|
|
const GValue * value, GParamSpec * pspec)
|
|
{
|
|
Panel *panel = PANEL (object);
|
|
|
|
switch (prop_id)
|
|
{
|
|
case PROP_SIZE:
|
|
panel_set_size (panel, g_value_get_int (value));
|
|
break;
|
|
case PROP_MONITOR:
|
|
panel_set_monitor (panel, g_value_get_int (value));
|
|
break;
|
|
case PROP_SCREEN_POSITION:
|
|
panel_set_screen_position (panel, g_value_get_enum (value));
|
|
break;
|
|
case PROP_XOFFSET:
|
|
panel_set_xoffset (panel, g_value_get_int (value));
|
|
break;
|
|
case PROP_YOFFSET:
|
|
panel_set_yoffset (panel, g_value_get_int (value));
|
|
break;
|
|
case PROP_AUTOHIDE:
|
|
panel_set_autohide (panel, g_value_get_boolean (value));
|
|
break;
|
|
case PROP_FULL_WIDTH:
|
|
panel_set_full_width (panel, g_value_get_int (value));
|
|
break;
|
|
case PROP_TRANSPARENCY:
|
|
panel_set_transparency (panel, g_value_get_int (value));
|
|
break;
|
|
case PROP_ACTIVE_TRANS:
|
|
panel_set_activetrans (panel, g_value_get_boolean (value));
|
|
break;
|
|
default:
|
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
|
break;
|
|
}
|
|
}
|
|
|
|
static void
|
|
panel_size_request (GtkWidget * widget, GtkRequisition * requisition)
|
|
{
|
|
GTK_WIDGET_CLASS (panel_parent_class)->size_request (widget, requisition);
|
|
|
|
requisition->width = MAX (MIN_SIZE, requisition->width);
|
|
requisition->height = MAX (MIN_SIZE, requisition->height);
|
|
}
|
|
|
|
static gboolean
|
|
panel_button_pressed (GtkWidget *widget, GdkEventButton *ev)
|
|
{
|
|
guint modifiers;
|
|
|
|
modifiers = gtk_accelerator_get_default_mod_mask ();
|
|
|
|
if (ev->button == 3 || (ev->button == 1 &&
|
|
(ev->state & modifiers) == GDK_CONTROL_MASK))
|
|
{
|
|
PanelPrivate *priv;
|
|
|
|
priv = PANEL (widget)->priv;
|
|
|
|
gtk_menu_set_screen (GTK_MENU (priv->menu),
|
|
gtk_widget_get_screen (widget));
|
|
|
|
gtk_menu_popup (GTK_MENU (priv->menu), NULL, NULL, NULL, NULL,
|
|
ev->button, ev->time);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
return GTK_WIDGET_CLASS (panel_parent_class)->button_press_event (widget,
|
|
ev);
|
|
}
|
|
|
|
/* DND dest */
|
|
static void
|
|
_panel_drag_data_received (GtkWidget *widget, GdkDragContext *context,
|
|
gint x, gint y, GtkSelectionData *data,
|
|
guint info, guint time, Panel *panel)
|
|
{
|
|
gboolean handled = FALSE;
|
|
|
|
DBG (" + drag data received: %d", info);
|
|
|
|
if (data->length > 0)
|
|
{
|
|
GtkWidget *plugin;
|
|
int index, oldindex = -1;
|
|
|
|
switch (info)
|
|
{
|
|
case TARGET_PLUGIN_NAME:
|
|
handled = TRUE;
|
|
index = xfce_itembar_get_drop_index (XFCE_ITEMBAR (widget),
|
|
x, y);
|
|
panel_insert_item (panel, (const char *)data->data, index);
|
|
break;
|
|
|
|
case TARGET_PLUGIN_WIDGET:
|
|
plugin = panel_dnd_get_plugin_from_data (data);
|
|
if (!plugin || !GTK_IS_WIDGET (plugin))
|
|
break;
|
|
handled = TRUE;
|
|
index = xfce_itembar_get_drop_index (XFCE_ITEMBAR (widget),
|
|
x, y);
|
|
if (plugin->parent != widget)
|
|
{
|
|
PanelPrivate *priv = panel->priv;
|
|
gtk_widget_reparent (plugin, widget);
|
|
|
|
xfce_panel_item_set_size (XFCE_PANEL_ITEM (plugin),
|
|
priv->size);
|
|
|
|
xfce_panel_item_set_screen_position (
|
|
XFCE_PANEL_ITEM (plugin), priv->screen_position);
|
|
|
|
xfce_itembar_set_child_expand (
|
|
XFCE_ITEMBAR (priv->itembar), plugin,
|
|
xfce_panel_item_get_expand (
|
|
XFCE_PANEL_ITEM (plugin)));
|
|
}
|
|
else /* only when moving on the same panel */
|
|
{
|
|
oldindex =
|
|
xfce_itembar_get_item_index (XFCE_ITEMBAR (widget),
|
|
plugin);
|
|
if (index > oldindex) index--;
|
|
}
|
|
|
|
if (index != oldindex)
|
|
xfce_itembar_reorder_child (XFCE_ITEMBAR (widget), plugin,
|
|
index);
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
gtk_drag_finish (context, handled, FALSE, time);
|
|
}
|
|
|
|
static gboolean
|
|
_panel_drag_drop (GtkWidget *widget, GdkDragContext *context,
|
|
gint x, gint y, guint time, Panel *panel)
|
|
{
|
|
GdkAtom atom = gtk_drag_dest_find_target (widget, context, NULL);
|
|
|
|
if (atom != GDK_NONE)
|
|
{
|
|
gtk_drag_get_data (widget, context, atom, time);
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
/* DND source */
|
|
static void
|
|
_panel_drag_begin (GtkWidget *widget, GdkDragContext *drag_context,
|
|
Panel *panel)
|
|
{
|
|
int x, y, rootx, rooty, w, h;
|
|
GtkWidget *plugin;
|
|
GdkPixbuf *pb;
|
|
PanelPrivate *priv = panel->priv;
|
|
|
|
DBG (" + drag begin");
|
|
|
|
if (priv->drag_widget)
|
|
{
|
|
plugin = priv->drag_widget;
|
|
|
|
/* allow menu to close, in order to not mess up the snapshot of the
|
|
* plugin */
|
|
while (gtk_events_pending ())
|
|
gtk_main_iteration ();
|
|
}
|
|
else
|
|
{
|
|
x = y = 0;
|
|
gdk_display_get_pointer (gtk_widget_get_display (widget),
|
|
NULL, &x, &y, NULL);
|
|
gdk_window_get_root_origin (widget->window, &rootx, &rooty);
|
|
x -= rootx;
|
|
y -= rooty;
|
|
|
|
plugin = xfce_itembar_get_item_at_point (XFCE_ITEMBAR (widget), x, y);
|
|
}
|
|
|
|
if (plugin)
|
|
{
|
|
GdkDrawable *d = GDK_DRAWABLE (plugin->window);
|
|
|
|
gdk_drawable_get_size (d, &w, &h);
|
|
pb = gdk_pixbuf_get_from_drawable (NULL, d, NULL, 0, 0, 0, 0, w, h);
|
|
gtk_drag_set_icon_pixbuf (drag_context, pb, 0, 0);
|
|
g_object_unref (pb);
|
|
|
|
priv->drag_widget = plugin;
|
|
}
|
|
else
|
|
DBG ("No Plugin");
|
|
}
|
|
|
|
static void
|
|
_panel_drag_end (GtkWidget *widget, GdkDragContext *drag_context,
|
|
Panel *panel)
|
|
{
|
|
PanelPrivate *priv = panel->priv;
|
|
|
|
priv->drag_widget = NULL;
|
|
|
|
if (!priv->edit_mode)
|
|
{
|
|
const GPtrArray *panels = panel_app_get_panel_list ();
|
|
int i;
|
|
|
|
for (i = 0; i < panels->len; ++i)
|
|
{
|
|
Panel *p = g_ptr_array_index (panels, i);
|
|
|
|
priv = p->priv;
|
|
|
|
xfce_itembar_lower_event_window (XFCE_ITEMBAR (priv->itembar));
|
|
panel_dnd_unset_dest (priv->itembar);
|
|
panel_dnd_unset_source (priv->itembar);
|
|
panel_set_items_sensitive (p, TRUE);
|
|
|
|
panel_unblock_autohide (p);
|
|
}
|
|
}
|
|
}
|
|
|
|
static void
|
|
_panel_drag_data_get (GtkWidget *widget, GdkDragContext *drag_context,
|
|
GtkSelectionData *data, guint info,
|
|
guint time, Panel *panel)
|
|
{
|
|
if (info == TARGET_PLUGIN_WIDGET)
|
|
{
|
|
PanelPrivate *priv = panel->priv;
|
|
|
|
if (priv->drag_widget)
|
|
{
|
|
panel_dnd_set_widget_data (data, priv->drag_widget);
|
|
}
|
|
}
|
|
}
|
|
|
|
static void
|
|
_panel_drag_data_delete (GtkWidget *widget, GdkDragContext *drag_context,
|
|
Panel *panel)
|
|
{
|
|
PanelPrivate *priv = panel->priv;
|
|
|
|
if (priv->drag_widget)
|
|
xfce_panel_item_remove (XFCE_PANEL_ITEM (priv->drag_widget));
|
|
|
|
priv->drag_widget = NULL;
|
|
}
|
|
|
|
/* pass through right-click events when the event window of itembar is raised
|
|
*/
|
|
static gboolean
|
|
_panel_itembar_button_pressed (GtkWidget *widget, GdkEventButton *ev,
|
|
Panel *panel)
|
|
{
|
|
if (xfce_itembar_event_window_is_raised (XFCE_ITEMBAR (widget)))
|
|
{
|
|
guint modifiers;
|
|
|
|
modifiers = gtk_accelerator_get_default_mod_mask ();
|
|
|
|
if (ev->button == 3 || (ev->button == 1 &&
|
|
(ev->state & modifiers) == GDK_CONTROL_MASK))
|
|
{
|
|
GtkWidget *plugin;
|
|
|
|
plugin = xfce_itembar_get_item_at_point (XFCE_ITEMBAR (widget),
|
|
ev->x, ev->y);
|
|
if (plugin)
|
|
{
|
|
gtk_widget_event (plugin, (GdkEvent *)ev);
|
|
return TRUE;
|
|
}
|
|
}
|
|
else if (ev->button == 1)
|
|
{
|
|
PanelPrivate *priv = panel->priv;
|
|
|
|
priv->drag_widget =
|
|
xfce_itembar_get_item_at_point (XFCE_ITEMBAR (widget),
|
|
ev->x, ev->y);
|
|
}
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
/* menu */
|
|
static GtkWidget *
|
|
_panel_create_menu (Panel *panel)
|
|
{
|
|
GtkWidget *menu, *mi, *img;
|
|
|
|
menu = gtk_menu_new ();
|
|
|
|
mi = gtk_image_menu_item_new_with_label (_("Customize Panel"));
|
|
gtk_widget_show (mi);
|
|
gtk_menu_shell_append (GTK_MENU_SHELL (menu), mi);
|
|
|
|
img = gtk_image_new_from_stock (GTK_STOCK_PREFERENCES, GTK_ICON_SIZE_MENU);
|
|
gtk_widget_show (img);
|
|
gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (mi), img);
|
|
|
|
g_signal_connect (mi, "activate", G_CALLBACK (panel_app_customize),
|
|
NULL);
|
|
|
|
mi = gtk_image_menu_item_new_with_label (_("Add Items"));
|
|
gtk_widget_show (mi);
|
|
gtk_menu_shell_append (GTK_MENU_SHELL (menu), mi);
|
|
|
|
img = gtk_image_new_from_stock (GTK_STOCK_ADD, GTK_ICON_SIZE_MENU);
|
|
gtk_widget_show (img);
|
|
gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (mi), img);
|
|
|
|
g_signal_connect_swapped (mi, "activate",
|
|
G_CALLBACK (panel_app_customize_items), NULL);
|
|
|
|
mi = gtk_separator_menu_item_new ();
|
|
gtk_widget_show (mi);
|
|
gtk_menu_shell_append (GTK_MENU_SHELL (menu), mi);
|
|
|
|
mi = gtk_image_menu_item_new_with_label (_("Quit"));
|
|
gtk_widget_show (mi);
|
|
gtk_menu_shell_append (GTK_MENU_SHELL (menu), mi);
|
|
|
|
img = gtk_image_new_from_stock (GTK_STOCK_QUIT, GTK_ICON_SIZE_MENU);
|
|
gtk_widget_show (img);
|
|
gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (mi), img);
|
|
|
|
g_signal_connect (mi, "activate", G_CALLBACK (panel_app_quit), NULL);
|
|
|
|
mi = gtk_image_menu_item_new_with_label (_("Restart"));
|
|
gtk_widget_show (mi);
|
|
gtk_menu_shell_append (GTK_MENU_SHELL (menu), mi);
|
|
|
|
img = gtk_image_new_from_stock (GTK_STOCK_REFRESH, GTK_ICON_SIZE_MENU);
|
|
gtk_widget_show (img);
|
|
gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (mi), img);
|
|
|
|
g_signal_connect (mi, "activate", G_CALLBACK (panel_app_restart), NULL);
|
|
|
|
mi = gtk_separator_menu_item_new ();
|
|
gtk_widget_show (mi);
|
|
gtk_menu_shell_append (GTK_MENU_SHELL (menu), mi);
|
|
|
|
mi = gtk_image_menu_item_new_with_label (_("About the Xfce Panel"));
|
|
gtk_widget_show (mi);
|
|
gtk_menu_shell_append (GTK_MENU_SHELL (menu), mi);
|
|
|
|
img = gtk_image_new_from_stock (GTK_STOCK_ABOUT, GTK_ICON_SIZE_MENU);
|
|
gtk_widget_show (img);
|
|
gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (mi), img);
|
|
|
|
g_signal_connect_swapped (mi, "activate", G_CALLBACK (panel_app_about),
|
|
panel);
|
|
|
|
return menu;
|
|
}
|
|
|
|
/* public API */
|
|
|
|
Panel *
|
|
panel_new (void)
|
|
{
|
|
return PANEL (g_object_new (PANEL_TYPE_PANEL, NULL));
|
|
}
|
|
|
|
void
|
|
panel_free_data (Panel *panel)
|
|
{
|
|
PanelPrivate *priv;
|
|
GList *l;
|
|
int i;
|
|
|
|
g_return_if_fail (PANEL_IS_PANEL (panel));
|
|
|
|
priv = panel->priv;
|
|
|
|
for (l = gtk_container_get_children (GTK_CONTAINER (priv->itembar));
|
|
l != NULL; l = l->next)
|
|
{
|
|
XfcePanelItem *item = l->data;
|
|
|
|
xfce_panel_item_free_data (item);
|
|
}
|
|
|
|
g_list_free (l);
|
|
|
|
/* give plugins the chance to quit */
|
|
for (i = 0; i < 10 &&
|
|
xfce_itembar_get_n_items (XFCE_ITEMBAR (priv->itembar)) != 0; ++i)
|
|
{
|
|
DBG (" + %d item(s) on the panel",
|
|
xfce_itembar_get_n_items (XFCE_ITEMBAR (priv->itembar)));
|
|
g_usleep (100000); /* 1/10 sec */
|
|
|
|
while (gtk_events_pending ())
|
|
gtk_main_iteration ();
|
|
}
|
|
|
|
}
|
|
|
|
/* items */
|
|
|
|
static void
|
|
_item_expand_changed (GtkWidget *item, gboolean expand, Panel *panel)
|
|
{
|
|
PanelPrivate *priv;
|
|
|
|
g_return_if_fail (PANEL_IS_PANEL (panel));
|
|
|
|
priv = panel->priv;
|
|
|
|
xfce_itembar_set_child_expand (XFCE_ITEMBAR (priv->itembar), item, expand);
|
|
}
|
|
|
|
static void
|
|
_item_start_move (GtkWidget *item, Panel *panel)
|
|
{
|
|
const GPtrArray *panels = panel_app_get_panel_list ();
|
|
PanelPrivate *priv;
|
|
int i;
|
|
|
|
for (i = 0; i < panels->len; ++i)
|
|
{
|
|
Panel *p = g_ptr_array_index (panels, i);
|
|
|
|
priv = p->priv;
|
|
|
|
if (!priv->edit_mode)
|
|
{
|
|
panel_set_items_sensitive (p, FALSE);
|
|
|
|
panel_dnd_set_dest (priv->itembar);
|
|
panel_dnd_set_widget_source (priv->itembar);
|
|
xfce_itembar_raise_event_window (XFCE_ITEMBAR (priv->itembar));
|
|
|
|
panel_block_autohide (p);
|
|
}
|
|
}
|
|
|
|
priv = panel->priv;
|
|
priv->drag_widget = item;
|
|
|
|
panel_dnd_begin_drag (priv->itembar);
|
|
}
|
|
|
|
static GtkWidget *
|
|
panel_create_item (Panel *panel, const char *name, const char *id)
|
|
{
|
|
PanelPrivate *priv;
|
|
GtkWidget *item = NULL;
|
|
|
|
priv = panel->priv;
|
|
|
|
if ((item = xfce_panel_item_manager_create_item (name, id,
|
|
priv->size, priv->screen_position)) != NULL)
|
|
{
|
|
g_signal_connect_swapped (item, "menu-deactivated",
|
|
G_CALLBACK (panel_menu_deactivated), panel);
|
|
|
|
g_signal_connect_swapped (item, "menu-opened",
|
|
G_CALLBACK (panel_menu_opened), panel);
|
|
|
|
g_signal_connect (item, "expand-changed",
|
|
G_CALLBACK (_item_expand_changed), panel);
|
|
|
|
g_signal_connect (item, "customize-panel",
|
|
G_CALLBACK (panel_app_customize), NULL);
|
|
|
|
g_signal_connect (item, "customize-items",
|
|
G_CALLBACK (panel_app_customize_items), NULL);
|
|
|
|
g_signal_connect (item, "move",
|
|
G_CALLBACK (_item_start_move), panel);
|
|
}
|
|
|
|
return item;
|
|
}
|
|
|
|
static void
|
|
panel_insert_widget (Panel *panel, GtkWidget *item, int position)
|
|
{
|
|
PanelPrivate *priv = panel->priv;
|
|
|
|
gtk_widget_show (item);
|
|
|
|
if (position == -1)
|
|
xfce_itembar_append (XFCE_ITEMBAR (priv->itembar), item);
|
|
else
|
|
xfce_itembar_insert (XFCE_ITEMBAR (priv->itembar), item, position);
|
|
|
|
xfce_itembar_set_child_expand (XFCE_ITEMBAR (priv->itembar), item,
|
|
xfce_panel_item_get_expand (XFCE_PANEL_ITEM (item)));
|
|
|
|
if (xfce_itembar_event_window_is_raised (XFCE_ITEMBAR (priv->itembar)))
|
|
xfce_panel_item_set_sensitive (XFCE_PANEL_ITEM (item), FALSE);
|
|
|
|
g_signal_connect (item, "destroy", G_CALLBACK (panel_app_queue_save),
|
|
NULL);
|
|
}
|
|
|
|
GtkWidget *
|
|
panel_add_item_with_id (Panel * panel, const char *name,
|
|
const char *id)
|
|
{
|
|
GtkWidget *item = NULL;
|
|
|
|
if ((item = panel_create_item (panel, name, id)) != NULL)
|
|
{
|
|
panel_insert_widget (panel, item, -1);
|
|
}
|
|
|
|
return item;
|
|
}
|
|
|
|
static char *
|
|
_panel_get_new_id (void)
|
|
{
|
|
static int counter = 0;
|
|
static char id[30];
|
|
|
|
/* unique number: pseudo-random time() + counter */
|
|
g_snprintf (id, 30, "%ld%d", time (NULL), counter++);
|
|
|
|
return id;
|
|
}
|
|
|
|
GtkWidget *
|
|
panel_add_item (Panel * panel, const char *name)
|
|
{
|
|
return panel_add_item_with_id (panel, name, _panel_get_new_id ());
|
|
}
|
|
|
|
GtkWidget *
|
|
panel_insert_item (Panel *panel, const char *name, int position)
|
|
{
|
|
GtkWidget *item = NULL;
|
|
|
|
if ((item = panel_create_item (panel, name, _panel_get_new_id ())) != NULL)
|
|
{
|
|
panel_insert_widget (panel, item, position);
|
|
}
|
|
|
|
return item;
|
|
}
|
|
|
|
/* configuration */
|
|
|
|
XfcePanelItemConfig *
|
|
panel_get_item_config_list (Panel * panel)
|
|
{
|
|
PanelPrivate *priv;
|
|
XfcePanelItemConfig *configlist = NULL;
|
|
GList *children, *l;
|
|
int len, i;
|
|
|
|
priv = panel->priv;
|
|
|
|
children = gtk_container_get_children (GTK_CONTAINER (priv->itembar));
|
|
|
|
len = g_list_length (children);
|
|
|
|
if (len != 0)
|
|
{
|
|
configlist = g_new (XfcePanelItemConfig, len + 1);
|
|
|
|
configlist[len].name = NULL;
|
|
configlist[len].id = NULL;
|
|
|
|
for (i = 0, l = children; l != NULL; l = l->next, ++i)
|
|
{
|
|
XfcePanelItem *item = l->data;
|
|
|
|
configlist[i].name = xfce_panel_item_get_name (item);
|
|
configlist[i].id = xfce_panel_item_get_id (item);
|
|
}
|
|
}
|
|
|
|
g_list_free (children);
|
|
|
|
return configlist;
|
|
}
|
|
|
|
void
|
|
panel_save_items (Panel *panel)
|
|
{
|
|
PanelPrivate *priv;
|
|
|
|
g_return_if_fail (PANEL_IS_PANEL (panel));
|
|
|
|
priv = panel->priv;
|
|
|
|
gtk_container_foreach (GTK_CONTAINER (priv->itembar),
|
|
(GtkCallback)xfce_panel_item_save, NULL);
|
|
}
|
|
|
|
/* convenience */
|
|
|
|
gboolean
|
|
panel_is_horizontal (Panel *panel)
|
|
{
|
|
return (GTK_ORIENTATION_HORIZONTAL ==
|
|
xfce_panel_window_get_orientation (XFCE_PANEL_WINDOW (panel)));
|
|
}
|
|
|
|
void
|
|
panel_set_items_sensitive (Panel *panel, gboolean sensitive)
|
|
{
|
|
PanelPrivate *priv = panel->priv;
|
|
GList *l, *children;
|
|
|
|
children = gtk_container_get_children (GTK_CONTAINER (priv->itembar));
|
|
|
|
for (l = children; l != NULL; l = l->next)
|
|
{
|
|
xfce_panel_item_set_sensitive (XFCE_PANEL_ITEM (l->data), sensitive);
|
|
}
|
|
|
|
g_list_free (children);
|
|
}
|
|
|
|
static void
|
|
panel_menu_deactivated (Panel *panel)
|
|
{
|
|
int x, y, w, h, px, py;
|
|
|
|
g_return_if_fail (PANEL_IS_PANEL (panel));
|
|
|
|
panel_unblock_autohide (panel);
|
|
|
|
gdk_display_get_pointer (gdk_display_get_default (), NULL, &px, &py, NULL);
|
|
|
|
gtk_window_get_position (GTK_WINDOW (panel), &x, &y);
|
|
gtk_window_get_size (GTK_WINDOW (panel), &w, &h);
|
|
|
|
if (px < x || px > x + w || py < y || py > y + h)
|
|
{
|
|
GdkEvent *ev = gdk_event_new (GDK_LEAVE_NOTIFY);
|
|
|
|
((GdkEventCrossing *) ev)->time = GDK_CURRENT_TIME;
|
|
((GdkEventCrossing *) ev)->detail = GDK_NOTIFY_NONLINEAR;
|
|
|
|
gtk_widget_event (GTK_WIDGET (panel), ev);
|
|
|
|
gdk_event_free (ev);
|
|
}
|
|
}
|
|
|
|
static void
|
|
panel_menu_opened (Panel *panel)
|
|
{
|
|
g_return_if_fail (PANEL_IS_PANEL (panel));
|
|
|
|
panel_block_autohide (panel);
|
|
}
|
|
|
|
|