Problem in the Gnome panel



Hello, all

I am having some problems with widget allocations in the Gnome panel.
The way the panel works is more or less like this:

	- The panel's main window and GtkFixed containers are created.

	- Applet modules are intialized.

	- The panel reads the user configuration file.  From there it
	  decides which applets to launch (i.e. create instances of).

	- When an applet is asked to create an instance of itself, the
	  applet module creates the applet's widget and asks the panel
	  to add that widget as an applet.

	- The panel is responsible for positioning the applet in a
	  place where it will not overlap other applets.

	- When all initialization is done, gtk_main() is called.

I am using a simple first-fit algorithm to find a suitable position
for the applets.  I need to query the position of the already-inserted
applets (by looking at their allocation field).  The problem is that
the applets may not have an allocation at the time I need to look at
it.

This is the code that registers an applet on the panel.  I would be
grateful if anyone has any suggestions about how to query the applets
about their position/size.

  Quartic

----------------------------------------------------------------------
static void
sort_applet_by_pos(GtkWidget *applet, gpointer data)
{
	GList     **list;
	GtkWidget *w;
	int        pos;

	list = data;
	pos  = 0;

	while (*list) {
		w = (*list)->data;
		
		if (applet->allocation.x < w->allocation.x)
			break;

		pos++;
		*list = (*list)->next;
	}

	*list = g_list_insert(*list, applet, pos);
}

static void
fix_applet_position(GtkWidget *applet, int *xpos, int *ypos)
{
	GList         *applets;
	GtkWidget     *w;
	GtkRequisition requisition;
	int            req_width;
	int            found;
	int            x;
	int            size;
	int            largest;
	int            x_for_largest;
	
	/* FIXME!!!  This is not working at all --- the widgets have
         * no allocation when I need them to :-(
	 */

	/* FIXME: This routine currently only handles the horizontal case of the panel */
	
	if ((*xpos != PANEL_UNKNOWN_APPLET_POSITION) &&
	    (*ypos != PANEL_UNKNOWN_APPLET_POSITION))
		return;

	*ypos = 0;

	applets = NULL;
	gtk_container_foreach(GTK_CONTAINER(the_panel->fixed),
			      sort_applet_by_pos,
			      &applets);

	gtk_widget_size_request(applet, &requisition);
	req_width = requisition.width;

	/* Find first fit */

	found         = FALSE;
	x             = 0;
	largest       = 0;
	x_for_largest = 0;

	for (; applets; applets = applets->next) {
		w = applets->data;

		size = w->allocation.x - x;

		if (size >= req_width) {
			found = TRUE;
			break;
		}

		if (size > largest) {
			largest = size;
			x_for_largest = x;
		}

		x = w->allocation.x + w->allocation.width;
	}

	if (found)
		*xpos = x;
	else {
		size = gdk_screen_width() - x;

		if (size >= req_width)
			*xpos = x;
		else
			*xpos = x_for_largest;
	}

	g_list_free(applets);
}


static void
register_toy(GtkWidget *applet, char *id, int xpos, int ypos, long flags)
{
	GtkWidget *eventbox;
	
	g_assert(applet != NULL);
	g_assert(id != NULL);

	/* We wrap the applet in a GtkEventBox so that we can capture events over it */

	eventbox = gtk_event_box_new();
	gtk_container_add(GTK_CONTAINER(eventbox), applet);

	gtk_widget_set_events(eventbox, gtk_widget_get_events(eventbox) | APPLET_EVENT_MASK);
	gtk_signal_connect(GTK_OBJECT(eventbox), "event", (GtkSignalFunc) panel_applet_event, NULL);
	bind_applet_events(applet, NULL);
	
	/* Attach our private data to the applet */

	gtk_object_set_data(GTK_OBJECT(eventbox), APPLET_CMD_FUNC, get_applet_cmd_func(id));
	gtk_object_set_data(GTK_OBJECT(eventbox), APPLET_FLAGS, (gpointer) flags);

	fix_applet_position(eventbox, &xpos, &ypos);

	gtk_fixed_put(GTK_FIXED(the_panel->fixed), eventbox, xpos, ypos);
	gtk_widget_show(eventbox);
	gtk_widget_show(applet);
}
----------------------------------------------------------------------



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]