Browse Source

* Allow windowlist to be opened with a command. Patch by Darren Salt (bug #2104).

* Add support for activating items by keyboard. Based on a patch by Darren Salt. Also bug #2104.


(Old svn revision: 22782)
upstream/xfce4-panel-4.10.1
Jasper Huijsmans 16 years ago
parent
commit
9e237eb9ba
  1. 18
      plugins/windowlist/Makefile.am
  2. 254
      plugins/windowlist/windowlist.c
  3. 96
      plugins/windowlist/xfce4-popup-windowlist.c
  4. 43
      plugins/windowlist/xfce4-popup-windowlist.h

18
plugins/windowlist/Makefile.am

@ -1,3 +1,18 @@
bin_PROGRAMS = xfce4-popup-windowlist
xfce4_popup_windowlist_SOURCES = \
xfce4-popup-windowlist.c \
xfce4-popup-windowlist.h
xfce4_popup_windowlist_CFLAGS = \
$(LIBX11_CFLAGS) \
$(GTK_CFLAGS)
xfce4_popup_windowlist_LDADD = \
$(LIBX11_LDFLAGS) \
$(LIBX11_LIBS) \
$(GTK_LIBS)
plugindir = $(libdir)/xfce4/panel-plugins
plugin_LTLIBRARIES = libwindowlist.la
@ -10,7 +25,8 @@ libwindowlist_la_SOURCES = \
windowlist.h \
windowlist.c \
windowlist-dialog.h \
windowlist-dialog.c
windowlist-dialog.c \
xfce4-popup-windowlist.h
libwindowlist_la_CFLAGS = \
-I$(top_srcdir) \

254
plugins/windowlist/windowlist.c

@ -37,11 +37,17 @@
#include <config.h>
#endif
#include <string.h>
#include <gdk/gdkkeysyms.h>
#include <libxfce4panel/xfce-arrow-button.h>
#include <libxfcegui4/netk-window-action-menu.h>
#include "windowlist.h"
#include "windowlist-dialog.h"
#include "xfce4-popup-windowlist.h"
typedef enum { WS_ADD = 1, WS_REMOVE } WorkspaceAction;
static gboolean
windowlist_blink (gpointer data);
@ -152,10 +158,10 @@ mi_destroyed (GtkObject *object,
static void
action_menu_deactivated (GtkMenu *menu,
GtkMenu *parent)
GtkMenu *parent)
{
DBG ("Destroy Action Menu");
gtk_menu_popdown (parent);
g_signal_emit_by_name (parent, "deactivate", 0);
}
@ -171,11 +177,11 @@ popup_action_menu (GtkWidget * widget,
menu = netk_create_window_action_menu (window);
g_signal_connect (menu, "deactivate",
G_CALLBACK (action_menu_deactivated), widget->parent);
gtk_menu_popup (GTK_MENU (menu), NULL, NULL, NULL, NULL, 0,
GDK_CURRENT_TIME);
g_signal_connect (menu, "deactivate",
G_CALLBACK (action_menu_deactivated), widget->parent);
}
static gboolean
@ -185,17 +191,20 @@ menulist_goto_window (GtkWidget *mi,
{
if (ev->button == 1) /* Goto workspace and show window */
{
gtk_menu_popdown (GTK_MENU (mi->parent));
netk_workspace_activate(netk_window_get_workspace(window));
netk_window_activate (window);
g_signal_emit_by_name (mi->parent, "deactivate", 0);
}
else if (ev->button == 2) /* Show window on current workspace */
{
gtk_menu_popdown (GTK_MENU (mi->parent));
netk_window_activate (window);
g_signal_emit_by_name (mi->parent, "deactivate", 0);
}
else if (ev->button == 3) /* Show the popup menu */
{
popup_action_menu (mi, window);
return TRUE;
}
return FALSE;
@ -240,6 +249,87 @@ menulist_remove_screen (GtkWidget *mi,
return FALSE;
}
static gboolean
menulist_keypress (GtkWidget *menu, GdkEventKey *ev, Windowlist *wl)
{
GdkEventButton evb;
GList *l;
GtkWidget *mi = NULL;
NetkWindow *window;
NetkWorkspace *workspace;
gpointer ws_action;
guint state;
for (l = GTK_MENU_SHELL (menu)->children; l != NULL; l = l->next)
{
if (GTK_WIDGET_STATE (l->data) == GTK_STATE_PRELIGHT)
{
mi = l->data;
break;
}
}
if (mi == NULL)
return FALSE;
state = ev->state & gtk_accelerator_get_default_mod_mask ();
switch (ev->keyval)
{
case GDK_space:
case GDK_Return:
case GDK_KP_Space:
case GDK_KP_Enter:
evb.button = 1;
break;
case GDK_Menu:
evb.button = 3;
break;
default:
return FALSE;
}
if (evb.button == 1)
{
if (state == GDK_SHIFT_MASK)
evb.button = 2;
else if (state == GDK_CONTROL_MASK)
evb.button = 3;
}
if((window = g_object_get_data (G_OBJECT (mi), "netk-window")) != NULL)
{
if (!NETK_IS_WINDOW (window))
return FALSE;
return menulist_goto_window (mi, &evb, window);
}
else if (evb.button == 1 &&
(workspace = g_object_get_data (G_OBJECT (mi), "netk-workspace"))
!= NULL)
{
if (!NETK_IS_WORKSPACE (workspace))
return FALSE;
return menulist_goto_workspace (mi, NULL, workspace);
}
else if (evb.button == 1 &&
(ws_action = g_object_get_data (G_OBJECT (mi), "ws-action"))
!= NULL)
{
if (GPOINTER_TO_INT (ws_action) == WS_REMOVE)
{
return menulist_remove_screen (mi, NULL, wl);
}
else
{
return menulist_add_screen (mi, NULL, wl);
}
}
return FALSE;
}
/**
* Menu position function
**/
@ -370,9 +460,9 @@ menulist_menu_item (NetkWindow *window,
}
static gboolean
menulist_toggle_menu (GtkToggleButton *button,
GdkEventButton *ev,
Windowlist * wl)
menulist_popup_menu (Windowlist * wl,
GdkEventButton *ev,
gboolean at_pointer)
{
GtkWidget *menu, *mi, *icon;
NetkWindow *window;
@ -383,9 +473,6 @@ menulist_toggle_menu (GtkToggleButton *button,
GList *windows, *li;
PangoFontDescription *italic, *bold;
if (ev->button != 1)
return FALSE;
/* Menu item styles */
italic = pango_font_description_from_string ("italic");
bold = pango_font_description_from_string ("bold");
@ -420,6 +507,9 @@ menulist_toggle_menu (GtkToggleButton *button,
mi = gtk_menu_item_new_with_label (ws_label);
gtk_menu_shell_append (GTK_MENU_SHELL (menu), mi);
g_free (ws_label);
g_object_set_data (G_OBJECT (mi), "netk-workspace", netk_workspace);
g_signal_connect (mi, "button-release-event",
G_CALLBACK (menulist_goto_workspace), netk_workspace);
@ -490,6 +580,8 @@ menulist_toggle_menu (GtkToggleButton *button,
&(menu->style->fg[GTK_STATE_INSENSITIVE]));
}
g_object_set_data (G_OBJECT (mi), "netk-window", window);
/* Connect some signals */
g_signal_connect (mi, "button-release-event",
G_CALLBACK (menulist_goto_window), window);
@ -510,10 +602,12 @@ menulist_toggle_menu (GtkToggleButton *button,
pango_font_description_free(italic);
pango_font_description_free(bold);
/* Show add/remove workspace buttons */
if (wl->show_workspace_actions)
{
int ws_action;
mi = gtk_separator_menu_item_new ();
gtk_menu_shell_append (GTK_MENU_SHELL (menu), mi);
@ -529,6 +623,9 @@ menulist_toggle_menu (GtkToggleButton *button,
mi = gtk_menu_item_new_with_label (_("Add workspace"));
}
ws_action = WS_ADD;
g_object_set_data (G_OBJECT (mi), "ws-action", GINT_TO_POINTER (ws_action));
gtk_menu_shell_append (GTK_MENU_SHELL (menu), mi);
g_signal_connect (mi, "button-release-event",
@ -536,34 +633,47 @@ menulist_toggle_menu (GtkToggleButton *button,
/* Remove workspace */
wscount = netk_screen_get_workspace_count (wl->screen);
netk_workspace = netk_screen_get_workspace (wl->screen, wscount-1);
rm_label = menulist_workspace_name (netk_workspace,
_("Remove Workspace %d"),
_("Remove Workspace '%s'"));
if (wl->show_window_icons)
{
mi = gtk_image_menu_item_new_with_label (rm_label);
icon = gtk_image_new_from_stock (GTK_STOCK_REMOVE,
GTK_ICON_SIZE_MENU);
gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (mi), icon);
}
else
{
mi = gtk_menu_item_new_with_label (rm_label);
}
g_free (rm_label);
gtk_menu_shell_append (GTK_MENU_SHELL (menu), mi);
g_signal_connect (mi, "button-release-event",
G_CALLBACK (menulist_remove_screen), wl);
if (wscount > 1)
{
netk_workspace = netk_screen_get_workspace (wl->screen, wscount-1);
rm_label = menulist_workspace_name (netk_workspace,
_("Remove Workspace %d"),
_("Remove Workspace '%s'"));
if (wl->show_window_icons)
{
mi = gtk_image_menu_item_new_with_label (rm_label);
icon = gtk_image_new_from_stock (GTK_STOCK_REMOVE,
GTK_ICON_SIZE_MENU);
gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (mi), icon);
}
else
{
mi = gtk_menu_item_new_with_label (rm_label);
}
g_free (rm_label);
ws_action = WS_REMOVE;
g_object_set_data (G_OBJECT (mi), "ws-action", GINT_TO_POINTER (ws_action));
gtk_menu_shell_append (GTK_MENU_SHELL (menu), mi);
g_signal_connect (mi, "button-release-event",
G_CALLBACK (menulist_remove_screen), wl);
}
}
/* key presses work on the menu, not the items */
g_signal_connect (menu, "key-press-event",
G_CALLBACK (menulist_keypress),
wl);
/* Activate toggle button */
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (wl->button), TRUE);
if (!at_pointer)
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (wl->button), TRUE);
/* Connect signal, show widgets and popup */
g_signal_connect (menu, "deactivate",
@ -572,12 +682,23 @@ menulist_toggle_menu (GtkToggleButton *button,
gtk_widget_show_all (menu);
gtk_menu_popup (GTK_MENU (menu), NULL, NULL,
(GtkMenuPositionFunc)windowlist_position_menu,
wl, 0, ev->time);
at_pointer ? NULL
: (GtkMenuPositionFunc)windowlist_position_menu,
wl, 0, ev ? ev->time : GDK_CURRENT_TIME);
return TRUE;
}
static gboolean
menulist_toggle_menu (GtkToggleButton *button,
GdkEventButton *ev,
Windowlist * wl)
{
if (ev->button != 1)
return FALSE;
return menulist_popup_menu (wl, ev, FALSE);
}
/**
* Check for urgent on workspaces
**/
@ -782,6 +903,59 @@ windowlist_active_window_changed (GtkWidget * w,
}
}
/**
* Handle user messages
**/
static gboolean
wl_message_received (GtkWidget *w, GdkEventClient *ev, gpointer user_data)
{
Windowlist *wl = user_data;
if (ev->data_format == 8 && *(ev->data.b) != '\0')
{
if (!strcmp (XFCE_WINDOW_LIST_MESSAGE, ev->data.b))
return menulist_popup_menu (wl, NULL, FALSE);
if (!strcmp (XFCE_WINDOW_LIST_AT_POINTER_MESSAGE, ev->data.b))
return menulist_popup_menu (wl, NULL, TRUE);
}
return FALSE;
}
static gboolean
wl_set_selection (Windowlist *wl)
{
GdkScreen *gscreen;
gchar selection_name[32];
Atom selection_atom;
GtkWidget *win;
Window xwin;
win = gtk_invisible_new ();
gtk_widget_realize (win);
xwin = GDK_WINDOW_XID (GTK_WIDGET (win)->window);
gscreen = gtk_widget_get_screen (win);
g_snprintf (selection_name, sizeof (selection_name),
XFCE_WINDOW_LIST_SELECTION"%d", gdk_screen_get_number (gscreen));
selection_atom = XInternAtom (GDK_DISPLAY (), selection_name, False);
if (XGetSelectionOwner (GDK_DISPLAY (), selection_atom))
{
gtk_widget_destroy (win);
return FALSE;
}
XSelectInput (GDK_DISPLAY (), xwin, PropertyChangeMask);
XSetSelectionOwner (GDK_DISPLAY (), selection_atom, xwin, GDK_CURRENT_TIME);
g_signal_connect (G_OBJECT (win), "client-event",
G_CALLBACK (wl_message_received), wl);
return TRUE;
}
/**
* Build the panel button and connect signals and styles
**/
@ -849,7 +1023,9 @@ windowlist_create_button (Windowlist * wl)
g_signal_connect (wl->button, "state-changed",
G_CALLBACK (windowlist_state_changed), wl);
wl_set_selection (wl);
gtk_widget_show_all (wl->button);
gtk_container_add (GTK_CONTAINER (wl->plugin), wl->button);

96
plugins/windowlist/xfce4-popup-windowlist.c

@ -0,0 +1,96 @@
/* $Id$
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, 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 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., 675 Mass Ave, Cambridge, MA 02139, USA.
(c) 2006 Darren Salt
Derived from xfdesktop's xfce4-popup-menu
(c) 2002-2006 Olivier Fourdan
*/
#include <gtk/gtk.h>
#include <glib.h>
#include <gdk/gdkx.h>
#include <X11/Xlib.h>
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdio.h>
#include "xfce4-popup-windowlist.h"
#ifdef HAVE_STRING_H
#include <string.h>
#endif
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
gboolean
xfce4_check_is_running (GtkWidget *widget, Window *xid)
{
GdkScreen *gscreen;
gchar selection_name[32];
Atom selection_atom;
gscreen = gtk_widget_get_screen (widget);
g_snprintf (selection_name,
sizeof (selection_name),
XFCE_WINDOW_LIST_SELECTION"%d",
gdk_screen_get_number (gscreen));
selection_atom = XInternAtom (GDK_DISPLAY (), selection_name, False);
if ((*xid = XGetSelectionOwner (GDK_DISPLAY (), selection_atom)))
return TRUE;
return FALSE;
}
int main (int argc,
char *argv[])
{
GdkEventClient gev;
GtkWidget *win;
Window id;
gtk_init (&argc, &argv);
win = gtk_invisible_new();
gtk_widget_realize(win);
gev.type = GDK_CLIENT_EVENT;
gev.window = win->window;
gev.send_event = TRUE;
gev.message_type = gdk_atom_intern ("STRING", FALSE);
gev.data_format = 8;
if (argc > 1 && !strcmp (argv[1], "-pointer"))
strcpy(gev.data.b, XFCE_WINDOW_LIST_AT_POINTER_MESSAGE);
else
strcpy(gev.data.b, XFCE_WINDOW_LIST_MESSAGE);
if (xfce4_check_is_running (win, &id))
gdk_event_send_client_message ((GdkEvent *)&gev,
(GdkNativeWindow)id);
else
g_warning ("Can't find the xfce4-panel window list to popup.\n");
gdk_flush();
gtk_widget_destroy (win);
return 0;
}

43
plugins/windowlist/xfce4-popup-windowlist.h

@ -0,0 +1,43 @@
/* $Id$
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, 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 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., 675 Mass Ave, Cambridge, MA 02139, USA.
(c) 2006 Darren Salt
Derived from xfdesktop panel-plugin/xfce4-popup-menu.h
(c) 2002-2006 Olivier Fourdan
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#ifndef INC_XFCE4_POPUP_MENU_H
#define INC_XFCE4_POPUP_MENU_H
#ifndef XFCE_WINDOW_LIST_MESSAGE
#define XFCE_WINDOW_LIST_MESSAGE "xfce4-wndlist-popup"
#endif /* XFCE_MENU_MESSAGE */
#ifndef XFCE_WINDOW_LIST_AT_POINTER_MESSAGE
#define XFCE_WINDOW_LIST_AT_POINTER_MESSAGE "xfce4-wndlist-atptr"
#endif /* XFCE_MENU_MESSAGE */
#ifndef XFCE_WINDOW_LIST_SELECTION
#define XFCE_WINDOW_LIST_SELECTION "XFCE_WINDOW_LIST_SEL"
#endif /* XFCE_MENU_SELECTION */
#endif /* INC_XFCE4_POPUP_MENU_H */
Loading…
Cancel
Save