Browse Source

Sizing improvements: no autohide when not on screen edge (Eduard Rocatelli), always keep inside the screen, keep centered or to the edge when size changes, e.g when changing settings or adding/rmoving items. All xinerama aware.

(Old svn revision: 3866)
tags/xfce4-panel-4.10.0
Jasper Huijsmans 18 years ago
parent
commit
1ac523e32d
5 changed files with 224 additions and 51 deletions
  1. +15
    -0
      NEWS
  2. +23
    -36
      TODO
  3. +1
    -1
      configure
  4. +1
    -1
      configure.ac
  5. +184
    -13
      panel/panel.c

+ 15
- 0
NEWS View File

@@ -1,3 +1,18 @@
Noteworthy updates to the xfce4 panel should be recorded here.

* 2003-09-30 Jasper Huijsmans <huysmans@users.sourceforge.net>

Fix crash when config file is corrupted. Still no clue about why the
corruption occurs in the first place :(

* 2003-09-14 Jasper Huijsmans <huysmans@users.sourceforge.net>

Documentation updated to new default configuration and other improvements.

* 2003-08-07 Jasper Huijsmans <huysmans@users.sourceforge.net>

Important i18n fix in xfce_support.c. Dialogs are now properly translated.

* 2003-07-25 Jasper Huijsmans <huysmans@users.sourceforge.net>

Improved autohide handling and reorientation.


+ 23
- 36
TODO View File

@@ -1,43 +1,30 @@
TODO list for xfce4
===================

Major features for 4.0
----------------------
* provide good default configuration


After 4.0
------------------------------------
* make panel a gtk widget
TODO
----
* gtk widgets (panel, controls)
- include move handles (steal code form GtkHandlebox)
- use properties and signals for settings

* do something smart with the panel behaviour depending on its position
- hiding
- popup arrow direction
- idea: keep panel on same alignment percentage (O% left aligned, 50%
centered, 100% right aligned).
- be a bit smarter when changing panel size (eg, keep at edge).

* Allow multiple panels?
- seriously look at mcs plugin. Most settings should become per panel
instead of global.

* make controls / control classes a widget or gobject
- use refcounting on classes to load / unload modules
- perhaps using a timeout
- perhaps use interfaces or derived widgets for controls
* unload unused plugins
* plugin library
- with API docs
* smarter resize/move
- popup arrow direction
- keep panel on same x/y alignment
* multiple panels
- Most settings should become per panel
* use icon theme spec
* drag to add/remove
* drag to move
* taskbar == panel instance?
* Move the exec_cmd stuff to libxfce4util/libxfcegui4

Ideas
-----
* plugins:
- dockapps support
- iconbox / task list
* write API docs for plugin writers

* new dialog for panel controls (treeview with dialog area)
adding/removing controls from here.
* Move to glib xml parsing. More work, but more speed / reduced memory usage
* Move to glib xml parsing. More work, but more speed /
reduced memory usage
* 2 plugins side by side
(like systembuttons)

* IMPORTANT: Move the exec_cmd stuff to libxfce4util/libxfcegui4 and
unify the interface!

+ 1
- 1
configure View File

@@ -1755,7 +1755,7 @@ fi

# Define the identity of the package.
PACKAGE=xfce4-panel
VERSION=4.0.0.1
VERSION=4.1.0


cat >>confdefs.h <<_ACEOF


+ 1
- 1
configure.ac View File

@@ -7,7 +7,7 @@ dnl

AC_INIT([panel/main.c])

AM_INIT_AUTOMAKE([xfce4-panel], [4.0.0.1])
AM_INIT_AUTOMAKE([xfce4-panel], [4.1.0])

AM_CONFIG_HEADER([config.h])



+ 184
- 13
panel/panel.c View File

@@ -76,7 +76,110 @@ static int scr = 0;
static int screen_width = 0;
static int screen_height = 0;

/* positioning */
struct XineramaScreen
{
int xmin, ymin;
int xmax, ymax;
};

struct XineramaScreen xinerama_scr = {0};

GtkRequisition panel_req = {0};

/* prototypes */
static void update_xinerama_coordinates (Panel *p);
static void panel_set_hidden (Panel * p, gboolean hide);
static void panel_reallocate (Panel *p, GtkRequisition *previous);

/* Xinerama fu */
static void
update_xinerama_coordinates (Panel *p)
{
int x, y;
g_return_if_fail(dpy != NULL);

x = p->toplevel->allocation.x + p->toplevel->allocation.width / 2;
y = p->toplevel->allocation.y + p->toplevel->allocation.height / 2;

xinerama_scr.xmin = MyDisplayX (x, y);
xinerama_scr.xmax = MyDisplayMaxX (dpy, scr, x, y);
xinerama_scr.ymin = MyDisplayY (x, y);
xinerama_scr.ymax = MyDisplayMaxY (dpy, scr, x, y);

DBG ("screen limits: (%d,%d) -> (%d,%d)",
xinerama_scr.xmin,xinerama_scr.ymin,
xinerama_scr.xmax,xinerama_scr.ymax);
}

static void
panel_reallocate (Panel *p, GtkRequisition *previous)
{
GtkRequisition new;
int xold, yold, xnew, ynew, xcenter, ycenter;
gboolean x_is_centered, y_is_centered;

gtk_widget_size_request(p->toplevel, &new);
xold = p->position.x;
yold = p->position.y;

xcenter = xinerama_scr.xmin + (xinerama_scr.xmax - xinerama_scr.xmin) / 2;
x_is_centered = (xcenter == xold + previous->width / 2);
ycenter = xinerama_scr.ymin + (xinerama_scr.ymax - xinerama_scr.ymin) / 2;
y_is_centered = (ycenter == yold + previous->height / 2);

/* initial new coordinates depend on centering */
if (x_is_centered)
xnew = xcenter - new.width / 2;
else
xnew = xold;
if (y_is_centered)
ynew = ycenter - new.height / 2;
else
ynew = yold;
/* if panel over right edge or panel previously on
* right edge then move to right edge */
if (xnew + new.width > xinerama_scr.xmax ||
xold + previous->width == xinerama_scr.xmax)
{
xnew = xinerama_scr.xmax - new.width;
}

/* if panel over bottom edge or panel previously on
* bottom edge then move to bottom edge */
if (ynew + new.height > xinerama_scr.ymax ||
yold + previous->height == xinerama_scr.ymax)
{
ynew = xinerama_scr.ymax - new.height;
}

if (xnew < xinerama_scr.xmin)
xnew = xinerama_scr.xmin;

if (ynew < xinerama_scr.ymin)
ynew = xinerama_scr.ymin;
DBG("%d,%d+%dx%d -> %d,%d+%dx%d",
xold, yold, previous->width, previous->height,
xnew, ynew, new.width, new.height);

if (xnew != xold || ynew != yold)
{
gtk_window_move (GTK_WINDOW(p->toplevel), xnew, ynew);

p->position.x = xnew;
p->position.y = ynew;

/* Need to save position here... */
write_panel_config ();
}
}

/* Move handle menu
* ----------------
@@ -215,6 +318,8 @@ handler_pressed_cb (GtkWidget * h, GdkEventButton * event)
static void
handler_move_end_cb (GtkWidget * h, gpointer data)
{
int x, y;
gtk_window_get_position (GTK_WINDOW (panel.toplevel),
&panel.position.x, &panel.position.y);

@@ -223,6 +328,32 @@ handler_move_end_cb (GtkWidget * h, gpointer data)
/* TODO: adjust arrow direction based on which quarter of the screen we
* are (Xinerama aware, of course ;) */

update_xinerama_coordinates(&panel);

/* keep panel inside the screen */

x = panel.position.x;
y = panel.position.y;
if (panel.position.x + panel_req.width > xinerama_scr.xmax)
x = xinerama_scr.xmax - panel_req.width;

if (panel.position.x < xinerama_scr.xmin)
x = xinerama_scr.xmin;
if (panel.position.y + panel_req.height > xinerama_scr.ymax)
y = xinerama_scr.ymax - panel_req.height;

if (panel.position.y < xinerama_scr.ymin)
y = xinerama_scr.ymin;

if (x != panel.position.x || y != panel.position.y)
{
gtk_window_move (GTK_WINDOW(panel.toplevel), x, y);
panel.position.x = x;
panel.position.y = y;
}
/* Need to save position here... */
write_panel_config ();
}
@@ -271,10 +402,11 @@ panel_set_hidden (Panel * p, gboolean hide)
/* xinerama aware screen coordinates */
if (pos.x < minx || pos.x >= maxx || pos.y < miny || pos.y >= maxy)
{
minx = MyDisplayX (pos.x, pos.y);
maxx = MyDisplayMaxX (dpy, scr, pos.x, pos.y);
miny = MyDisplayY (pos.x, pos.y);
maxy = MyDisplayMaxY (dpy, scr, pos.x, pos.y);
update_xinerama_coordinates (p);
minx = xinerama_scr.xmin;
maxx = xinerama_scr.xmax;
miny = xinerama_scr.ymin;
maxy = xinerama_scr.ymax;

centerx = minx + (maxx - minx) / 2;
centery = miny + (maxy - miny) / 2;
@@ -288,9 +420,15 @@ panel_set_hidden (Panel * p, gboolean hide)
/* Handle the resize */
if (hide)
{
/* Only hide when the panel is on the edge of the screen
* Thanks to Eduard Rocatelli for pointing this out */
/* Depending on orientation, resize */
if (settings.orientation == VERTICAL)
{
if (pos.x > minx && pos.x + req.width < maxx)
return;

if (pos.x < centerx)
x = pos.x;
else
@@ -302,6 +440,9 @@ panel_set_hidden (Panel * p, gboolean hide)
}
else
{
if (pos.y > miny && pos.y + req.height < maxy)
return;

if (pos.y < centery)
y = pos.y;
else
@@ -321,13 +462,13 @@ panel_set_hidden (Panel * p, gboolean hide)
}

/* keep inside the screen */
if (x < 0)
x = 0;
if (x < minx)
x = minx;
else if (x > maxx - HIDDEN_SIZE)
x = maxx - HIDDEN_SIZE;

if (y < 0)
y = 0;
if (y < miny)
y = miny;
else if (y > maxy - HIDDEN_SIZE)
y = maxy - HIDDEN_SIZE;
@@ -476,6 +617,24 @@ panel_delete_cb (GtkWidget * window, GdkEvent * ev, gpointer data)
return TRUE;
}

static void
panel_allocate_cb (GtkWidget * window, GtkAllocation *allocation, Panel *p)
{
DBG ("%d x %d -> %d x %d",
panel_req.width, panel_req.height,
allocation->width, allocation->height);

if (panel_req.width != allocation->width ||
panel_req.height != allocation->height)
{
if (!(panel_req.width == 0 && panel_req.height == 0))
panel_reallocate (p, &panel_req);

panel_req.width = allocation->width;
panel_req.height = allocation->height;
}
}

static GtkWidget *
create_panel_window (void)
{
@@ -495,7 +654,10 @@ create_panel_window (void)
gtk_window_set_icon (window, pb);
g_object_unref (pb);

g_signal_connect (w, "delete-event", G_CALLBACK (panel_delete_cb), NULL);
g_signal_connect (w, "delete-event", G_CALLBACK (panel_delete_cb),
NULL);
g_signal_connect (w, "size-allocate", G_CALLBACK (panel_allocate_cb),
&panel);

return w;
}
@@ -646,6 +808,8 @@ create_panel (void)
panel.position.y = y;
panel_set_position ();

update_xinerama_coordinates(&panel);
if (hidden)
panel_set_autohide(TRUE);
}
@@ -713,10 +877,19 @@ panel_set_orientation (int orientation)
groups_pack (GTK_BOX (panel.group_box));
groups_set_orientation (orientation);

/* reset panel requisition to prevent 'size-allocate'
* handler from wrongly adjusting the position */
panel_req.width = panel_req.height = 0;

/* TODO: find out why position doesn't get properly set in
* set_size function */
panel.position.x = panel.position.y = -1;
/* also sets position */
panel_set_size (settings.size);

panel.position.x = panel.position.y = -1;
panel_set_position();
gtk_widget_show(panel.toplevel);
set_window_layer (panel.toplevel, settings.layer);
set_window_skip (panel.toplevel);
@@ -737,7 +910,7 @@ panel_set_layer (int layer)

set_window_layer (panel.toplevel, layer);
if (layer == TOP)
if (layer == ABOVE)
gtk_window_present(GTK_WINDOW(panel.toplevel));
}

@@ -754,8 +927,6 @@ panel_set_size (int size)
groups_set_size (size);
handle_set_size (panel.handles[LEFT], size);
handle_set_size (panel.handles[RIGHT], size);

panel_set_position ();
}

void


Loading…
Cancel
Save