From 35653dc8e5673414af836412d484a4300c53b2da Mon Sep 17 00:00:00 2001 From: Thomas Leonard Date: Thu, 16 May 2002 19:36:58 +0000 Subject: [PATCH] r1484: Position iconified windows sensibly. --- ROX-Filer/Help/Changes | 1 + ROX-Filer/src/panel.c | 22 +++++++++++++++ ROX-Filer/src/panel.h | 1 + ROX-Filer/src/pinboard.c | 71 ++++++++++++++++++++++++++++++++++++++++++++++-- ROX-Filer/src/pinboard.h | 2 +- ROX-Filer/src/tasklist.c | 21 +++++--------- 6 files changed, 101 insertions(+), 17 deletions(-) diff --git a/ROX-Filer/Help/Changes b/ROX-Filer/Help/Changes index a97c0912..4884dc99 100644 --- a/ROX-Filer/Help/Changes +++ b/ROX-Filer/Help/Changes @@ -5,6 +5,7 @@ 16-May-2002 ~~~~~~~~~~~ Pinboard background colour option works again. +Position iconified windows sensibly. Bugfix: Typing too fast into the minibuffer could miss characters. 15-May-2002 diff --git a/ROX-Filer/src/panel.c b/ROX-Filer/src/panel.c index 11643534..baac82b1 100644 --- a/ROX-Filer/src/panel.c +++ b/ROX-Filer/src/panel.c @@ -403,6 +403,28 @@ gboolean panel_add(PanelSide side, return TRUE; } +/* Add the area covered by the panels to the region */ +void panel_mark_used(GdkRegion *used) +{ + int i; + + for (i = 0; i < PANEL_NUMBER_OF_SIDES; i++) + { + Panel *panel = current_panel[i]; + GdkRectangle rect; + + if (!panel) + continue; + + gdk_window_get_root_origin(panel->window->window, + &rect.x, &rect.y); + rect.width = panel->window->allocation.width; + rect.height = panel->window->allocation.height; + + gdk_region_union_with_rect(used, &rect); + } +} + /**************************************************************** * INTERNAL FUNCTIONS * ****************************************************************/ diff --git a/ROX-Filer/src/panel.h b/ROX-Filer/src/panel.h index c3652084..6531e7a7 100644 --- a/ROX-Filer/src/panel.h +++ b/ROX-Filer/src/panel.h @@ -40,5 +40,6 @@ void panel_save(Panel *panel); gboolean panel_add(PanelSide side, const gchar *path, const gchar *label, gboolean after); +void panel_mark_used(GdkRegion *used); #endif /* _PANEL_H */ diff --git a/ROX-Filer/src/pinboard.c b/ROX-Filer/src/pinboard.c index 28c5ea6e..857bfc3b 100644 --- a/ROX-Filer/src/pinboard.c +++ b/ROX-Filer/src/pinboard.c @@ -53,6 +53,7 @@ #include "menu.h" #include "xml.h" #include "tasklist.h" +#include "panel.h" /* For panel_mark_used() */ static gboolean tmp_icon_selected = FALSE; /* When dragging */ @@ -201,6 +202,7 @@ static void drag_backdrop_dropped(GtkWidget *frame, guint32 time, GtkWidget *dialog); static void backdrop_response(GtkWidget *dialog, gint response, gpointer data); +static void find_free_rect(Pinboard *pinboard, GdkRectangle *rect); /**************************************************************** @@ -333,11 +335,23 @@ const char *pinboard_get_name(void) /* Add widget to the pinboard. Caller is responsible for coping with pinboard * being cleared. */ -void pinboard_add_widget(GtkWidget *widget, int x, int y) +void pinboard_add_widget(GtkWidget *widget) { + GtkRequisition req; + GdkRectangle rect; + g_return_if_fail(current_pinboard != NULL); - gtk_fixed_put(GTK_FIXED(current_pinboard->fixed), widget, x, y); + gtk_fixed_put(GTK_FIXED(current_pinboard->fixed), widget, 0, 0); + + gtk_widget_size_request(widget, &req); + + rect.width = req.width; + rect.height = req.height; + find_free_rect(current_pinboard, &rect); + + gtk_fixed_move(GTK_FIXED(current_pinboard->fixed), + widget, rect.x, rect.y); } /* Add a new icon to the background. @@ -1953,3 +1967,56 @@ static void set_backdrop(const gchar *path, BackdropStyle style) pinboard_save(); } + +/* Finds a free area on the pinboard large enough for the width and height + * of the given rectangle, by filling in the x and y fields of 'rect'. + * The search order respects user preferences. + * If no area is free, returns any old area. + */ +static void find_free_rect(Pinboard *pinboard, GdkRectangle *rect) +{ + GdkRegion *used; + GList *next; + + used = gdk_region_new(); + + panel_mark_used(used); + + /* Subtract the used areas... */ + + next = GTK_FIXED(pinboard->fixed)->children; + for (; next; next = next->next) + { + GtkFixedChild *fix = (GtkFixedChild *) next->data; + GdkRectangle used_rect; + + if (!GTK_WIDGET_VISIBLE(fix->widget)) + continue; + + used_rect.x = fix->x; + used_rect.y = fix->y; + used_rect.width = fix->widget->requisition.width; + used_rect.height = fix->widget->requisition.height; + + gdk_region_union_with_rect(used, &used_rect); + } + + /* Find the first free area (yes, this isn't exactly pretty, but + * it works). If you know a better (fast!) algorithm, let me know! + */ + + for (rect->y = 0; rect->y < screen_height; rect->y += 32) + { + for (rect->x = 0; rect->x < screen_width; rect->x += 32) + { + if (gdk_region_rect_in(used, rect) == + GDK_OVERLAP_RECTANGLE_OUT) + goto out; + } + } + + rect->x = 0; + rect->y = 0; +out: + gdk_region_destroy(used); +} diff --git a/ROX-Filer/src/pinboard.h b/ROX-Filer/src/pinboard.h index e2b95ab1..bf9f1659 100644 --- a/ROX-Filer/src/pinboard.h +++ b/ROX-Filer/src/pinboard.h @@ -28,6 +28,6 @@ const gchar *pinboard_get_name(void); void pinboard_set_backdrop(void); void pinboard_set_backdrop_app(const gchar *app); GdkWindow *pinboard_get_window(void); -void pinboard_add_widget(GtkWidget *widget, int x, int y); +void pinboard_add_widget(GtkWidget *widget); #endif /* _PINBOARD_H */ diff --git a/ROX-Filer/src/tasklist.c b/ROX-Filer/src/tasklist.c index 00a675d5..0e42e2c2 100644 --- a/ROX-Filer/src/tasklist.c +++ b/ROX-Filer/src/tasklist.c @@ -71,10 +71,6 @@ static GdkAtom xa__NET_WM_ICON_GEOMETRY = GDK_NONE; */ static GHashTable *known = NULL; /* XID -> IconWindow */ -/* Top-left corner of next icon to be created */ -static int iconify_next_x = 0; -static int iconify_next_y = 0; - /* Static prototypes */ static void remove_window(Window win); static void tasklist_update(gboolean to_empty); @@ -86,7 +82,6 @@ static gboolean xid_equal(XID *a, XID *b); static void state_changed(IconWindow *win); static void show_icon(IconWindow *win); static void icon_win_free(IconWindow *win); -static void set_iconify_pos(IconWindow *win); static void update_style(gpointer key, gpointer data, gpointer user_data); /**************************************************************** @@ -372,7 +367,9 @@ static void add_window(Window win) window_check_status(w); +#if 0 set_iconify_pos(w); +#endif if (gdk_error_trap_pop() != Success) g_hash_table_remove(known, &win); @@ -536,7 +533,6 @@ static void button_released(GtkWidget *widget, IconWindow *win) static void show_icon(IconWindow *win) { static MaskedPixmap *icon = NULL; - GtkRequisition req; GtkWidget *vbox; g_return_if_fail(win->widget == NULL); @@ -569,14 +565,9 @@ static void show_icon(IconWindow *win) g_signal_connect(win->widget, "released", G_CALLBACK(button_released), win); - pinboard_add_widget(win->widget, iconify_next_x, iconify_next_y); - - gtk_widget_show_all(win->widget); - gtk_widget_size_request(win->widget, &req); - - iconify_next_y += req.height; - if (iconify_next_y + req.height > screen_height) - iconify_next_y = 0; + gtk_widget_show_all(vbox); /* So the size comes out right */ + pinboard_add_widget(win->widget); + gtk_widget_show(win->widget); } /* A window has been destroyed/expanded -- remove its icon */ @@ -602,6 +593,7 @@ static void state_changed(IconWindow *win) hide_icon(win); } +#if 0 /* Set the _NET_WM_ICON_GEOMETRY property, which indicates where this window * will be iconified to. Should be inside a push/pop. */ @@ -618,6 +610,7 @@ static void set_iconify_pos(IconWindow *win) gdk_x11_atom_to_xatom(xa__NET_WM_ICON_GEOMETRY), XA_CARDINAL, 32, PropModeReplace, (guchar *) data, 4); } +#endif static void update_style(gpointer key, gpointer data, gpointer user_data) { -- 2.11.4.GIT