Only in src/: Makefile diff -Pua src/Makefile.in fixed/Makefile.in --- src/Makefile.in 2004-07-15 07:10:54.000000000 -0400 +++ fixed/Makefile.in 2005-09-18 08:19:39.000000000 -0400 @@ -17,9 +17,9 @@ PROG = Pager -SRCS = choices.c gui_support.c main.c options.c rox_gettext.c +SRCS = choices.c gui_support.c main.c options.c rox_gettext.c window-menu.c -OBJECTS = choices.o gui_support.o main.o options.o rox_gettext.o +OBJECTS = choices.o gui_support.o main.o options.o rox_gettext.o window-menu.o ############ Things to keep the same Only in src/: choices.c Only in src/: choices.h diff -Pua src/config.h.in fixed/config.h.in --- src/config.h.in 2004-07-15 07:10:54.000000000 -0400 +++ fixed/config.h.in 2005-09-18 08:19:52.000000000 -0400 @@ -2,6 +2,8 @@ #define PROJECT "Pager" +#undef HAVE_WNCK_CREATE_WINDOW_MENU + #include "rox_gettext.h" #define _(String) rox_gettext(String) /* Short for gettext_noop() - marks a string as translatable without Only in src/: configure diff -Pua src/configure.in fixed/configure.in --- src/configure.in 2003-07-16 06:38:38.000000000 -0400 +++ fixed/configure.in 2005-09-18 08:20:05.000000000 -0400 @@ -82,6 +82,12 @@ AC_C_CONST AC_TYPE_SIZE_T +dnl does libwnck have wnck_create_window_menu() ? +ac_LIBS="$LIBS" +LIBS="$LIBS `pkg-config --libs libwnck-1.0`" +AC_CHECK_FUNCS(wnck_create_window_menu) +LIBS="$ac_LIBS" + dnl Extract version info from AppInfo.xml AC_MSG_CHECKING(extracting version information) [ Only in src/: global.h Only in src/: gui_support.c Only in src/: gui_support.h diff -Pua src/main.c fixed/main.c --- src/main.c 2004-08-15 13:19:39.000000000 -0400 +++ fixed/main.c 2005-09-18 08:19:24.000000000 -0400 @@ -18,6 +18,8 @@ #include "options.h" #include "choices.h" +#include "window-menu.h" + char *app_dir = NULL; static GdkWindow *socket = NULL; /* NULL => Not an applet */ @@ -28,6 +30,13 @@ static Option n_rows; +static int +workspace_at_point (WnckPager *pager, + int x, + int y, + int *viewport_x, + int *viewport_y); + /* Read the contents of this property. g_free() the result. */ static char *read_property(GdkWindow *window, GdkAtom prop, GdkAtom type, gint *out_length) @@ -169,14 +178,47 @@ return window_list; } +/* Returns a list of the windows on the active workspace */ +static GList *get_workspace_window_list(WnckWorkspace *work_space, + GList *wins) +{ + GList *window_list = NULL; + while (wins) + { + WnckWindow *window = WNCK_WINDOW(wins->data); + if (wnck_window_is_on_workspace(window,work_space)) + window_list = g_list_append(window_list,wins->data); + wins = wins->next; + } + wins = g_list_first(wins); + return window_list; +} + +/* Returns the selected workspace from the pager widget */ +static WnckWorkspace *get_selected_workspace(GdkEventButton *event) +{ + int space_number; + + space_number = workspace_at_point(WNCK_PAGER(pager), + event->x, event->y, + NULL, NULL); + if (space_number == -1) + return wnck_screen_get_active_workspace(screen); + + return wnck_screen_get_workspace(screen, space_number); +} + static gboolean button_event(GtkWidget *widget, GdkEventButton *event, gpointer user_data) { if (event->button == 3) { + WnckWorkspace *work_space; + GtkWidget *menu_all; GtkWidget *menu; GtkWidget *item; + GList *wins_all; GList *wins; gchar *pos = NULL; @@ -186,12 +228,28 @@ gdk_atom_intern("_ROX_PANEL_MENU_POS", FALSE)); } - - wins = get_window_list(); + wins_all = get_window_list(); +#ifdef HAVE_WNCK_CREATE_WINDOW_MENU + menu_all = wnck_create_window_menu(wins_all); +#else + menu_all = our_create_window_menu(wins_all); +#endif + + work_space = get_selected_workspace(event); + wins = get_workspace_window_list(work_space,wins_all); +#ifdef HAVE_WNCK_CREATE_WINDOW_MENU menu = wnck_create_window_menu(wins); +#else + menu = our_create_window_menu(wins); +#endif item = gtk_menu_item_new(); + + item = gtk_menu_item_new_with_label(_("All windows")); + gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), menu_all); + gtk_widget_show(item); + gtk_menu_append(GTK_MENU(menu), item); gtk_widget_show(item); @@ -260,8 +318,7 @@ { double aspect; Orient orient = panel_get_orient(); - int n_screens = wnck_screen_get_workspace_count( - wnck_screen_get_default()); + int n_screens = wnck_screen_get_workspace_count(screen); *width = alloc_width; *height = alloc_height; @@ -467,3 +524,175 @@ return 0; } + +/* Taken from libwnck/pager.c */ +#define POINT_IN_RECT(xcoord, ycoord, rect) \ + ((xcoord) >= (rect).x && \ + (xcoord) < ((rect).x + (rect).width) && \ + (ycoord) >= (rect).y && \ + (ycoord) < ((rect).y + (rect).height)) + +#define N_SCREEN_CONNECTIONS 11 + +static void +get_workspace_rect (WnckPager *pager, + int space, + GdkRectangle *rect) +{ + int hsize, vsize; + int n_spaces; + int spaces_per_row; + GtkWidget *widget; + int col, row; + int focus_width; + int nrows = n_rows.int_value; + + gtk_widget_style_get (GTK_WIDGET (pager), + "focus-line-width", &focus_width, + NULL); + + widget = GTK_WIDGET (pager); + + hsize = widget->allocation.width - 2 * focus_width; + vsize = widget->allocation.height - 2 * focus_width; + + /* if (pager->priv->shadow_type != GTK_SHADOW_NONE) */ + { + hsize -= 2 * widget->style->xthickness; + vsize -= 2 * widget->style->ythickness; + } + + n_spaces = wnck_screen_get_workspace_count (wnck_screen_get_default ()); + + g_return_if_fail(nrows > 0); + spaces_per_row = (n_spaces + nrows - 1) / nrows; + + if (panel_get_orient() == ORIENT_VERT) + { + rect->width = (hsize - (nrows - 1)) / nrows; + rect->height = (vsize - (spaces_per_row - 1)) / spaces_per_row; + + col = space / spaces_per_row; + row = space % spaces_per_row; + rect->x = (rect->width + 1) * col; + rect->y = (rect->height + 1) * row; + + if (col == nrows - 1) + rect->width = hsize - rect->x; + + if (row == spaces_per_row - 1) + rect->height = vsize - rect->y; + } + else + { + rect->width = (hsize - (spaces_per_row - 1)) / spaces_per_row; + rect->height = (vsize - (nrows - 1)) / nrows; + + col = space % spaces_per_row; + row = space / spaces_per_row; + rect->x = (rect->width + 1) * col; + rect->y = (rect->height + 1) * row; + + if (col == spaces_per_row - 1) + rect->width = hsize - rect->x; + + if (row == nrows - 1) + rect->height = vsize - rect->y; + } + + rect->x += focus_width; + rect->y += focus_width; + + /* if (pager->priv->shadow_type != GTK_SHADOW_NONE) */ + { + rect->x += widget->style->xthickness; + rect->y += widget->style->ythickness; + } +} + +static int +workspace_at_point (WnckPager *pager, + int x, + int y, + int *viewport_x, + int *viewport_y) +{ + GtkWidget *widget; + int i; + int n_spaces; + int focus_width; + int xthickness; + int ythickness; + + widget = GTK_WIDGET (pager); + + gtk_widget_style_get (GTK_WIDGET (pager), + "focus-line-width", &focus_width, + NULL); + + xthickness = focus_width + widget->style->xthickness; + ythickness = focus_width + widget->style->ythickness; + + n_spaces = wnck_screen_get_workspace_count (screen); + + i = 0; + while (i < n_spaces) + { + GdkRectangle rect; + + get_workspace_rect (pager, i, &rect); + + /* if (pager->priv->shadow_type != GTK_SHADOW_NONE) */ + { + /* If workspace is on the edge, pretend points on the frame + * belong to the workspace. + */ + + GtkWidget *widget = GTK_WIDGET (pager); + + if (rect.x == xthickness) + { + rect.x = 0; + rect.width += xthickness; + } + if (rect.y == ythickness) + { + rect.y = 0; + rect.height += ythickness; + } + if (rect.y + rect.height == widget->allocation.height - ythickness) + { + rect.height += ythickness; + } + if (rect.x + rect.width == widget->allocation.width - xthickness) + { + rect.width += xthickness; + } + } + + if (POINT_IN_RECT (x, y, rect)) + { + double width_ratio, height_ratio; + WnckWorkspace *space; + + space = wnck_screen_get_workspace (screen, i); + g_assert (space != NULL); + + /* Scale x, y mouse coords to corresponding screenwide viewport coords */ + + width_ratio = (double) wnck_workspace_get_width (space) / (double) rect.width; + height_ratio = (double) wnck_workspace_get_height (space) / (double) rect.height; + + if (viewport_x) + *viewport_x = width_ratio * (x - rect.x); + if (viewport_y) + *viewport_y = height_ratio * (y - rect.y); + + return i; + } + + ++i; + } + + return -1; +} Only in src/: options.c Only in src/: options.h Only in src/: po Only in src/: rox_gettext.c Only in src/: rox_gettext.h diff -Pua src/window-menu.c fixed/window-menu.c --- src/window-menu.c 1969-12-31 19:00:00.000000000 -0500 +++ fixed/window-menu.c 2005-09-18 08:20:16.000000000 -0400 @@ -0,0 +1,137 @@ +/* window menu */ + +/* + * Copyright (C) 2001 Havoc Pennington + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/* Modified by Lucas Hazel and Stephen Watson for use in the Pager + * application because it was removed from later libwnck versions + */ + +#include "config.h" +#ifndef HAVE_WNCK_CREATE_WINDOW_MENU + +#include "window-menu.h" + +static void object_weak_notify (gpointer data, + GObject *obj); +static void window_weak_notify (gpointer data, + GObject *window); + +static void +window_weak_notify (gpointer data, + GObject *window) +{ + g_object_set_data (G_OBJECT (data), "wnck-window-data", NULL); + g_object_weak_unref (G_OBJECT (data), + object_weak_notify, + window); +} + +static void +set_window (GObject *obj, + WnckWindow *win) +{ + g_object_set_data (obj, "wnck-window-data", win); + if (win) + { + g_object_weak_ref (G_OBJECT (win), window_weak_notify, obj); + g_object_weak_ref (obj, object_weak_notify, win); + } +} + +static void +object_weak_notify (gpointer data, + GObject *obj) +{ + g_object_weak_unref (G_OBJECT (data), + window_weak_notify, + obj); +} + +static WnckWindow* +get_window (GObject *obj) +{ + return g_object_get_data (obj, "wnck-window-data"); +} + +static void +item_activated_callback (GtkWidget *menu_item, + gpointer data) +{ + WnckWindow *win; + + win = get_window (G_OBJECT (menu_item)); + + if (win == NULL) + return; + + wnck_window_activate (win, 0); +} + +GtkWidget* +our_create_window_menu (GList *windows) +{ + GList *tmp; + GtkWidget *menu; + + menu = gtk_menu_new (); + + tmp = windows; + + while (tmp != NULL) + { + WnckWindow *win = WNCK_WINDOW (tmp->data); + GdkPixbuf *icon; + const char *title; + GtkWidget *mi; + + icon = wnck_window_get_icon (win); + title = wnck_window_get_icon_name (win); + + if (icon) + { + GtkWidget *image; + + image = gtk_image_new_from_pixbuf (icon); + + mi = gtk_image_menu_item_new_with_label (title); + gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (mi), + image); + } + else + { + mi = gtk_menu_item_new_with_label (title); + } + + g_signal_connect (G_OBJECT (mi), "activate", + G_CALLBACK (item_activated_callback), NULL); + + set_window (G_OBJECT (mi), win); + + gtk_widget_show (mi); + + gtk_menu_shell_append (GTK_MENU_SHELL (menu), mi); + + tmp = tmp->next; + } + + return menu; +} + +#endif /* HAVE_WNCK_CREATE_WINDOW_MENU */ diff -Pua src/window-menu.h fixed/window-menu.h --- src/window-menu.h 1969-12-31 19:00:00.000000000 -0500 +++ fixed/window-menu.h 2005-09-18 08:20:27.000000000 -0400 @@ -0,0 +1,14 @@ +#ifndef HAVE_WNCK_CREATE_WINDOW_MENU + +#ifndef WINDOW_MENU_H +#define WINDOW_MENU_H + +#define WNCK_I_KNOW_THIS_IS_UNSTABLE + +#include + +extern GtkWidget* our_create_window_menu (GList *windows); + +#endif /* WINDOW_MENU_H */ + +#endif /* HAVE_WNCK_CREATE_WINDOW_MENU */