You are not logged in.
Pages: 1
Hi,
I'm trying to patch xfwm4 (xfce's window manager) to cycle windows differently. With the stock code I hold down Alt and press Tab repeatedly, and it cycles through a list, and when I release Alt and Tab it raises and focuses the window I selected from the list.
The behaviour I want is for it to not display a list at all, and focus the window the moment I press Tab (whilst pressing Alt). So basically I want it to not display a list and to raise + focus the new window instantly as it cycles.
Here is the source code for the window cycling, which I got from here: http://www.p0llux.be/xfce/xfce-4.6.1/sr … .1.tar.bz2 (from src/cycle.c):
/* $Id: cycle.c 29683 2009-03-25 10:34:05Z olivier $
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., Inc., 51 Franklin Street, Fifth Floor, Boston,
MA 02110-1301, USA.
oroborus - (c) 2001 Ken Lynch
xfwm4 - (c) 2002-2009 Olivier Fourdan
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <X11/X.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xatom.h>
#include <X11/extensions/shape.h>
#include <glib.h>
#include <gdk/gdk.h>
#include <gdk/gdkx.h>
#include <gtk/gtk.h>
#include <libxfce4util/libxfce4util.h>
#include "client.h"
#include "focus.h"
#include "frame.h"
#include "settings.h"
#include "stacking.h"
#include "tabwin.h"
#include "transients.h"
#include "wireframe.h"
#include "workspaces.h"
#include "event_filter.h"
typedef struct _ClientCycleData ClientCycleData;
struct _ClientCycleData
{
Client *c;
Tabwin *tabwin;
Window wireframe;
int cycle_range;
};
static eventFilterStatus
clientCycleEventFilter (XEvent * xevent, gpointer data)
{
ScreenInfo *screen_info;
DisplayInfo *display_info;
ClientCycleData *passdata;
Client *c, *removed;
eventFilterStatus status;
KeyCode cancel;
int key, modifier;
gboolean key_pressed, cycling, gone;
TRACE ("entering clientCycleEventFilter");
passdata = (ClientCycleData *) data;
if (passdata->c == NULL)
{
return EVENT_FILTER_CONTINUE;
}
c = passdata->c;
screen_info = c->screen_info;
display_info = screen_info->display_info;
cancel = screen_info->params->keys[KEY_CANCEL].keycode;
modifier = screen_info->params->keys[KEY_CYCLE_WINDOWS].modifier;
status = EVENT_FILTER_STOP;
cycling = TRUE;
gone = FALSE;
/* Update the display time */
myDisplayUpdateCurrentTime (display_info, xevent);
switch (xevent->type)
{
case DestroyNotify:
removed = myScreenGetClientFromWindow (screen_info, ((XDestroyWindowEvent *) xevent)->window, SEARCH_WINDOW);
gone |= (c == removed);
c = tabwinRemoveClient(passdata->tabwin, removed);
passdata->c = c;
status = EVENT_FILTER_CONTINUE;
/* Walk through */
case UnmapNotify:
removed = myScreenGetClientFromWindow (screen_info, ((XUnmapEvent *) xevent)->window, SEARCH_WINDOW);
gone |= (c == removed);
c = tabwinRemoveClient(passdata->tabwin, removed);
passdata->c = c;
status = EVENT_FILTER_CONTINUE;
/* Walk through */
case KeyPress:
key_pressed = (xevent->type == KeyPress);
if (gone || key_pressed)
{
if (key_pressed)
{
Client *c2 = NULL;
key = myScreenGetKeyPressed (screen_info, (XKeyEvent *) xevent);
/*
* We cannot simply check for key == KEY_CANCEL here because of the
* mofidier being pressed, so we need to look at the keycode directly.
*/
if (xevent->xkey.keycode == cancel)
{
c2 = tabwinGetHead (passdata->tabwin);
cycling = FALSE;
}
else if (key == KEY_CYCLE_REVERSE_WINDOWS)
{
TRACE ("Cycle: previous");
c2 = tabwinSelectPrev(passdata->tabwin);
}
else if (key == KEY_CYCLE_WINDOWS)
{
TRACE ("Cycle: next");
c2 = tabwinSelectNext(passdata->tabwin);
}
if (c2)
{
c = c2;
passdata->c = c;
}
/* If last key press event had not our modifier pressed, finish cycling */
if (!(xevent->xkey.state & modifier))
{
cycling = FALSE;
}
}
if (cycling)
{
if (c)
{
if (passdata->wireframe)
{
wireframeUpdate (c, passdata->wireframe);
}
}
else
{
cycling = FALSE;
}
}
}
break;
case KeyRelease:
{
int keysym = XLookupKeysym (&xevent->xkey, 0);
if (!(xevent->xkey.state & modifier) ||
(IsModifierKey(keysym) && (keysym != XK_Shift_L) && (keysym != XK_Shift_R)))
{
cycling = FALSE;
}
}
break;
case ButtonPress:
case ButtonRelease:
case EnterNotify:
case MotionNotify:
break;
default:
status = EVENT_FILTER_CONTINUE;
break;
}
if (!cycling)
{
TRACE ("event loop now finished");
gtk_main_quit ();
}
return status;
}
void
clientCycle (Client * c, XKeyEvent * ev)
{
ScreenInfo *screen_info;
DisplayInfo *display_info;
ClientCycleData passdata;
gboolean g1, g2;
int key;
g_return_if_fail (c != NULL);
TRACE ("entering clientCycle");
screen_info = c->screen_info;
display_info = screen_info->display_info;
g1 = myScreenGrabKeyboard (screen_info, ev->time);
g2 = myScreenGrabPointer (screen_info, LeaveWindowMask, None, ev->time);
if (!g1 || !g2)
{
TRACE ("grab failed in clientCycle");
gdk_beep ();
myScreenUngrabKeyboard (screen_info, CurrentTime);
myScreenUngrabPointer (screen_info, CurrentTime);
return;
}
if (screen_info->params->cycle_hidden)
{
passdata.cycle_range = INCLUDE_HIDDEN;
}
else
{
passdata.cycle_range = 0;
}
if (!screen_info->params->cycle_minimum)
{
passdata.cycle_range |= INCLUDE_SKIP_TASKBAR | INCLUDE_SKIP_PAGER;
}
if (screen_info->params->cycle_workspaces)
{
passdata.cycle_range |= INCLUDE_ALL_WORKSPACES;
}
key = myScreenGetKeyPressed (screen_info, ev);
if (key == KEY_CYCLE_REVERSE_WINDOWS)
{
passdata.c = clientGetPrevious (c, passdata.cycle_range);
}
else
{
passdata.c = clientGetNext (c, passdata.cycle_range);
}
passdata.wireframe = None;
/* If there is one single client, and if it's eligible for focus, use it */
if ((passdata.c == NULL) && (c != clientGetFocus()) &&
clientSelectMask (c, passdata.cycle_range, WINDOW_REGULAR_FOCUSABLE))
{
passdata.c = c;
}
if (passdata.c)
{
TRACE ("entering cycle loop");
if (screen_info->params->cycle_draw_frame)
{
passdata.wireframe = wireframeCreate (passdata.c);
}
passdata.tabwin = tabwinCreate (passdata.c->screen_info->gscr, c,
passdata.c, passdata.cycle_range,
screen_info->params->cycle_workspaces);
eventFilterPush (display_info->xfilter, clientCycleEventFilter, &passdata);
gtk_main ();
eventFilterPop (display_info->xfilter);
TRACE ("leaving cycle loop");
tabwinDestroy (passdata.tabwin);
g_free (passdata.tabwin);
if (passdata.wireframe)
{
wireframeDelete (screen_info, passdata.wireframe);
}
updateXserverTime (display_info);
}
if (passdata.c)
{
Client *focused;
Client *sibling;
int workspace;
c = passdata.c;
workspace = c->win_workspace;
focused = clientGetFocus ();
if (workspace != screen_info->current_ws)
{
workspaceSwitch (screen_info, workspace, c, FALSE, myDisplayGetCurrentTime (display_info));
}
if ((focused) && (passdata.c != focused))
{
clientClearAllShowDesktop (screen_info);
clientAdjustFullscreenLayer (focused, FALSE);
}
sibling = clientGetTransientFor(c);
clientRaise (sibling, None);
clientShow (sibling, TRUE);
clientSetFocus (screen_info, c, myDisplayGetCurrentTime (display_info), NO_FOCUS_FLAG);
clientSetLastRaise (c);
}
/*
* Use CurrentTime instead of actual last event time to make sure
* that the grab is released in any case.
*/
myScreenUngrabKeyboard (screen_info, CurrentTime);
myScreenUngrabPointer (screen_info, CurrentTime);
}
I don't know any C so I hope someone can help me.
Thanks.
Last edited by 9nqksfhn (2009-08-04 18:47:55)
Offline
This patch might do it. Not tested at all, not even compile tested. I don't use XFCE.
--- cycle.c.orig 2009-08-04 15:04:17.871189695 -0400
+++ cycle.c 2009-08-04 15:07:21.298206230 -0400
@@ -126,11 +126,13 @@
{
TRACE ("Cycle: previous");
c2 = tabwinSelectPrev(passdata->tabwin);
+ cycling = FALSE;
}
else if (key == KEY_CYCLE_WINDOWS)
{
TRACE ("Cycle: next");
c2 = tabwinSelectNext(passdata->tabwin);
+ cycling = FALSE;
}
if (c2)
{
Offline
BTW I already get this behaviour by hovering the mouse cursor over the xfce4-panel tasklist plugin and rolling the scroll wheel.
Here is the source code for the xfce4-panel tasklist plugin, which I got from here: http://www.p0llux.be/xfce/xfce-4.6.1/sr … .1.tar.bz2 (from plugins/tasklist/tasklist.c and tasklist-dialogs.c)
/* $Id: tasklist.c 26626 2008-02-18 12:42:14Z nick $
*
* Copyright (c) 2005-2007 Jasper Huijsmans <jasper@xfce.org>
* Copyright (c) 2007 Nick Schermer <nick@xfce.org>
*
* This program 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 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 Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#ifdef HAVE_STRING_H
#include <string.h>
#endif
#include <libwnck/libwnck.h>
#include <libxfce4util/libxfce4util.h>
#include <libxfce4panel/xfce-hvbox.h>
#include "tasklist.h"
#include "tasklist-dialogs.h"
#define TASKLIST_HANDLE_SIZE (8)
/* prototypes */
static gboolean tasklist_handle_exposed (GtkWidget *widget,
GdkEventExpose *event,
TasklistPlugin *tasklist);
static GdkPixbuf *tasklist_icon_loader (const gchar *name,
gint size,
guint flags,
TasklistPlugin *tasklist);
static TasklistPlugin *tasklist_plugin_new (XfcePanelPlugin *panel_plugin);
static void tasklist_plugin_screen_changed (TasklistPlugin *tasklist,
GdkScreen *previous_screen);
static void tasklist_plugin_orientation_changed (TasklistPlugin *tasklist,
GtkOrientation orientation);
static gboolean tasklist_plugin_size_changed (TasklistPlugin *tasklist,
guint size);
static void tasklist_plugin_size_request (TasklistPlugin *tasklist,
GtkRequisition *requisition);
static void tasklist_plugin_read (TasklistPlugin *tasklist);
static void tasklist_plugin_free (TasklistPlugin *tasklist);
static void tasklist_plugin_construct (XfcePanelPlugin *panel_plugin);
/* register with the panel */
XFCE_PANEL_PLUGIN_REGISTER_INTERNAL (tasklist_plugin_construct);
gboolean
tasklist_using_xinerama (XfcePanelPlugin *panel_plugin)
{
return (gdk_screen_get_n_monitors (gtk_widget_get_screen (GTK_WIDGET (panel_plugin))) > 1);
}
static gboolean
tasklist_handle_exposed (GtkWidget *widget,
GdkEventExpose *event,
TasklistPlugin *tasklist)
{
GtkOrientation orientation;
gint x, y, w, h;
if (GTK_WIDGET_DRAWABLE (widget))
{
/* get the panel orientation */
orientation = xfce_panel_plugin_get_orientation (tasklist->panel_plugin);
/* set sizes */
x = widget->allocation.x;
y = widget->allocation.y;
w = widget->allocation.width;
h = widget->allocation.height;
if (orientation == GTK_ORIENTATION_HORIZONTAL)
{
y += widget->style->ythickness;
h -= 2 * widget->style->ythickness;
}
else
{
x += widget->style->xthickness;
w -= 2 * widget->style->xthickness;
}
gtk_paint_handle (widget->style, widget->window,
GTK_WIDGET_STATE (widget), GTK_SHADOW_NONE,
&(event->area), widget, "handlebox",
x, y, w, h, orientation);
return TRUE;
}
return FALSE;
}
static GdkPixbuf *
tasklist_icon_loader (const gchar *name,
gint size,
guint flags,
TasklistPlugin *tasklist)
{
GdkPixbuf *pixbuf = NULL;
gchar *base = NULL;
const gchar *p;
/* do nothing on invalid names */
if (G_UNLIKELY (name == NULL || *name == '\0'))
return NULL;
if (g_path_is_absolute (name))
{
if (g_file_test (name, G_FILE_TEST_EXISTS))
{
/* directly load the file */
pixbuf = gdk_pixbuf_new_from_file_at_size (name, size, size, NULL);
}
else
{
/* get the base name */
base = g_path_get_basename (name);
/* use this function to try again */
pixbuf = tasklist_icon_loader (base, size, flags, tasklist);
/* cleanup */
g_free (base);
}
}
else
{
/* strip prefix */
p = strrchr (name, '.');
if (G_UNLIKELY (p))
base = g_strndup (name, p - name);
/* load the icon */
pixbuf = gtk_icon_theme_load_icon (tasklist->icon_theme, base ? base : name, size, 0, NULL);
/* cleanup */
g_free (base);
}
return pixbuf;
}
static TasklistPlugin *
tasklist_plugin_new (XfcePanelPlugin *panel_plugin)
{
TasklistPlugin *tasklist;
GdkScreen *screen;
gint screen_n;
/* allocate structure */
tasklist = panel_slice_new0 (TasklistPlugin);
/* init data */
tasklist->panel_plugin = panel_plugin;
/* read settings */
tasklist_plugin_read (tasklist);
/* create hvbox */
tasklist->box = xfce_hvbox_new (xfce_panel_plugin_get_orientation (panel_plugin), FALSE, 0);
gtk_container_add (GTK_CONTAINER (panel_plugin), tasklist->box);
gtk_widget_show (tasklist->box);
/* create handle */
tasklist->handle = gtk_alignment_new (0.0, 0.0, 0.0, 0.0);
gtk_widget_set_size_request (tasklist->handle, TASKLIST_HANDLE_SIZE, TASKLIST_HANDLE_SIZE);
gtk_box_pack_start (GTK_BOX (tasklist->box), tasklist->handle, FALSE, FALSE, 0);
g_signal_connect (tasklist->handle, "expose-event", G_CALLBACK (tasklist_handle_exposed), tasklist);
if (tasklist->show_handles)
gtk_widget_show (tasklist->handle);
/* get the current screen number */
screen = gtk_widget_get_screen (GTK_WIDGET (panel_plugin));
screen_n = gdk_screen_get_number (screen);
/* set the icon theme */
tasklist->icon_theme = gtk_icon_theme_get_for_screen (screen);
/* create tasklist */
tasklist->list = wnck_tasklist_new (wnck_screen_get (screen_n));
gtk_box_pack_start (GTK_BOX (tasklist->box), tasklist->list, FALSE, FALSE, 0);
gtk_widget_show (tasklist->list);
/* set the tasklist settings */
wnck_tasklist_set_include_all_workspaces (WNCK_TASKLIST (tasklist->list), tasklist->all_workspaces);
wnck_tasklist_set_grouping (WNCK_TASKLIST (tasklist->list), tasklist->grouping);
wnck_tasklist_set_button_relief (WNCK_TASKLIST (tasklist->list), tasklist->flat_buttons ? GTK_RELIEF_NONE : GTK_RELIEF_NORMAL);
wnck_tasklist_set_icon_loader (WNCK_TASKLIST (tasklist->list), (WnckLoadIconFunction) tasklist_icon_loader, tasklist, NULL);
return tasklist;
}
static void
tasklist_plugin_screen_changed (TasklistPlugin *tasklist,
GdkScreen *previous_screen)
{
GdkScreen *screen;
WnckScreen *wnck_screen;
/* get the new screen */
screen = gtk_widget_get_screen (GTK_WIDGET (tasklist->panel_plugin));
if (G_UNLIKELY (screen == NULL))
screen = gdk_screen_get_default ();
/* get the wnck screen */
wnck_screen = wnck_screen_get (gdk_screen_get_number (screen));
/* set the new tasklist screen */
wnck_tasklist_set_screen (WNCK_TASKLIST (tasklist->list), wnck_screen);
/* set the icon theme */
tasklist->icon_theme = gtk_icon_theme_get_for_screen (screen);
}
static void
tasklist_plugin_orientation_changed (TasklistPlugin *tasklist,
GtkOrientation orientation)
{
/* set the new orientation of the hvbox */
xfce_hvbox_set_orientation (XFCE_HVBOX (tasklist->box), orientation);
/* redraw the handle */
gtk_widget_queue_draw (tasklist->handle);
}
gboolean
tasklist_plugin_size_changed (TasklistPlugin *tasklist,
guint size)
{
/* size is handled in the size_request function */
return TRUE;
}
static void
tasklist_plugin_size_request (TasklistPlugin *tasklist,
GtkRequisition *requisition)
{
const gint *size_hints;
gint length;
gint size;
GtkOrientation orientation;
/* get the size hints */
size_hints = wnck_tasklist_get_size_hint_list (WNCK_TASKLIST (tasklist->list), &length);
/* check for pairs of 2 */
if (G_LIKELY (length > 0))
{
/* get the first size */
size = size_hints[0];
/* add the handle size */
if (tasklist->show_handles)
size += TASKLIST_HANDLE_SIZE;
/* use the requested size when it is bigger then the prefered size */
if (tasklist->width > size)
size = tasklist->width;
/* get plugin orientation */
orientation = xfce_panel_plugin_get_orientation (tasklist->panel_plugin);
/* set the panel size */
requisition->width = requisition->height = xfce_panel_plugin_get_size (tasklist->panel_plugin);
/* set the requested plugin size */
if (orientation == GTK_ORIENTATION_HORIZONTAL)
requisition->width = size;
else
requisition->height = size;
/* save the requested size */
tasklist->req_size = size;
}
}
static void
tasklist_plugin_size_allocate (TasklistPlugin *tasklist,
GtkAllocation *allocation)
{
GtkOrientation orientation;
gint a_size, p_size;
/* get orientation */
orientation = xfce_panel_plugin_get_orientation (tasklist->panel_plugin);
/* get plugin size */
p_size = xfce_panel_plugin_get_size (tasklist->panel_plugin);
if (orientation == GTK_ORIENTATION_HORIZONTAL)
a_size = MIN (tasklist->req_size, allocation->width);
else
a_size = MIN (tasklist->req_size, allocation->height);
if (tasklist->show_handles)
a_size -= TASKLIST_HANDLE_SIZE;
/* force the size request of the taskbar */
if (orientation == GTK_ORIENTATION_HORIZONTAL)
gtk_widget_set_size_request (GTK_WIDGET (tasklist->list), a_size, p_size);
else
gtk_widget_set_size_request (GTK_WIDGET (tasklist->list), p_size, a_size);
}
static void
tasklist_plugin_read (TasklistPlugin *tasklist)
{
gchar *file;
XfceRc *rc;
/* set defaults */
tasklist->grouping = WNCK_TASKLIST_AUTO_GROUP;
tasklist->all_workspaces = FALSE;
tasklist->expand = TRUE;
tasklist->flat_buttons = TRUE;
tasklist->show_handles = TRUE;
tasklist->width = 300;
/* get rc file name */
file = xfce_panel_plugin_lookup_rc_file (tasklist->panel_plugin);
if (G_LIKELY (file))
{
/* open the file, readonly */
rc = xfce_rc_simple_open (file, TRUE);
/* cleanup */
g_free (file);
if (G_LIKELY (rc))
{
/* read settings */
tasklist->grouping = xfce_rc_read_int_entry (rc, "grouping", tasklist->grouping);
tasklist->all_workspaces = xfce_rc_read_bool_entry (rc, "all_workspaces", tasklist->all_workspaces);
tasklist->flat_buttons = xfce_rc_read_bool_entry (rc, "flat_buttons", tasklist->flat_buttons);
tasklist->show_handles = xfce_rc_read_bool_entry (rc, "show_handles", tasklist->show_handles);
tasklist->width = xfce_rc_read_int_entry (rc, "width",tasklist->width);
/* only set expand flag if xinerama is used */
if (tasklist_using_xinerama (tasklist->panel_plugin))
tasklist->expand = xfce_rc_read_bool_entry (rc, "expand", tasklist->expand);
/* close the rc file */
xfce_rc_close (rc);
}
}
}
void
tasklist_plugin_write (TasklistPlugin *tasklist)
{
gchar *file;
XfceRc *rc;
/* get rc file name, create it if needed */
file = xfce_panel_plugin_save_location (tasklist->panel_plugin, TRUE);
if (G_LIKELY (file))
{
/* open the file, writable */
rc = xfce_rc_simple_open (file, FALSE);
/* cleanup */
g_free (file);
if (G_LIKELY (rc))
{
/* write settings */
xfce_rc_write_int_entry (rc, "grouping", tasklist->grouping);
xfce_rc_write_int_entry (rc, "width", tasklist->width);
xfce_rc_write_bool_entry (rc, "all_workspaces", tasklist->all_workspaces);
xfce_rc_write_bool_entry (rc, "expand", tasklist->expand);
xfce_rc_write_bool_entry (rc, "flat_buttons", tasklist->flat_buttons);
xfce_rc_write_bool_entry (rc, "show_handles", tasklist->show_handles);
/* close the rc file */
xfce_rc_close (rc);
}
}
}
static void
tasklist_plugin_free (TasklistPlugin *tasklist)
{
GtkWidget *dialog;
/* destroy the dialog */
dialog = g_object_get_data (G_OBJECT (tasklist->panel_plugin), I_("dialog"));
if (dialog)
gtk_widget_destroy (dialog);
/* disconnect screen changed signal */
g_signal_handler_disconnect (G_OBJECT (tasklist->panel_plugin), tasklist->screen_changed_id);
/* free slice */
panel_slice_free (TasklistPlugin, tasklist);
}
static void
tasklist_plugin_construct (XfcePanelPlugin *panel_plugin)
{
TasklistPlugin *tasklist;
/* create the tray panel plugin */
tasklist = tasklist_plugin_new (panel_plugin);
/* set the action widgets and show configure */
xfce_panel_plugin_add_action_widget (panel_plugin, tasklist->handle);
xfce_panel_plugin_menu_show_configure (panel_plugin);
/* whether to expand the plugin */
xfce_panel_plugin_set_expand (panel_plugin, tasklist->expand);
/* connect plugin signals */
g_signal_connect_swapped (G_OBJECT (panel_plugin), "orientation-changed",
G_CALLBACK (tasklist_plugin_orientation_changed), tasklist);
g_signal_connect_swapped (G_OBJECT (panel_plugin), "size-changed",
G_CALLBACK (tasklist_plugin_size_changed), tasklist);
g_signal_connect_swapped (G_OBJECT (panel_plugin), "size-request",
G_CALLBACK (tasklist_plugin_size_request), tasklist);
g_signal_connect_swapped (G_OBJECT (panel_plugin), "size-allocate",
G_CALLBACK (tasklist_plugin_size_allocate), tasklist);
g_signal_connect_swapped (G_OBJECT (panel_plugin), "save",
G_CALLBACK (tasklist_plugin_write), tasklist);
g_signal_connect_swapped (G_OBJECT (panel_plugin), "free-data",
G_CALLBACK (tasklist_plugin_free), tasklist);
g_signal_connect_swapped (G_OBJECT (panel_plugin), "configure-plugin",
G_CALLBACK (tasklist_dialogs_configure), tasklist);
/* screen changed signal */
tasklist->screen_changed_id =
g_signal_connect_swapped (G_OBJECT (panel_plugin), "screen-changed",
G_CALLBACK (tasklist_plugin_screen_changed), tasklist);
}
/* $Id: tasklist-dialogs.c 29188 2009-01-12 17:08:56Z nick $
*
* Copyright (c) 2005-2007 Jasper Huijsmans <jasper@xfce.org>
*
* This program 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 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 Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include "tasklist.h"
#include "tasklist-dialogs.h"
/* prototypes */
static void tasklist_all_workspaces_toggled (GtkToggleButton *tb,
TasklistPlugin *tasklist);
static void tasklist_grouping_changed (GtkComboBox *cb,
TasklistPlugin *tasklist);
static void tasklist_expand_toggled (GtkToggleButton *tb,
TasklistPlugin *tasklist);
static void tasklist_flat_buttons_toggled (GtkToggleButton *tb,
TasklistPlugin *tasklist);
static void tasklist_show_handle_toggled (GtkToggleButton *tb,
TasklistPlugin *tasklist);
static void tasklist_width_changed (GtkSpinButton *sb,
TasklistPlugin *tasklist);
static void tasklist_dialog_response (GtkWidget *dlg,
gint reponse,
TasklistPlugin *tasklist);
static void
tasklist_all_workspaces_toggled (GtkToggleButton *tb,
TasklistPlugin *tasklist)
{
tasklist->all_workspaces = gtk_toggle_button_get_active (tb);
wnck_tasklist_set_include_all_workspaces (WNCK_TASKLIST (tasklist->list),
tasklist->all_workspaces);
}
static void
tasklist_grouping_changed (GtkComboBox *cb,
TasklistPlugin *tasklist)
{
tasklist->grouping = gtk_combo_box_get_active (cb);
wnck_tasklist_set_grouping (WNCK_TASKLIST (tasklist->list),
tasklist->grouping);
}
static void
tasklist_expand_toggled (GtkToggleButton *tb,
TasklistPlugin *tasklist)
{
tasklist->expand = gtk_toggle_button_get_active (tb);
xfce_panel_plugin_set_expand (tasklist->panel_plugin, tasklist->expand);
}
static void
tasklist_flat_buttons_toggled (GtkToggleButton *tb,
TasklistPlugin *tasklist)
{
tasklist->flat_buttons = gtk_toggle_button_get_active (tb);
wnck_tasklist_set_button_relief (WNCK_TASKLIST (tasklist->list),
tasklist->flat_buttons ?
GTK_RELIEF_NONE : GTK_RELIEF_NORMAL);
}
static void
tasklist_show_handle_toggled (GtkToggleButton *tb,
TasklistPlugin *tasklist)
{
tasklist->show_handles = gtk_toggle_button_get_active (tb);
if (tasklist->show_handles)
gtk_widget_show (tasklist->handle);
else
gtk_widget_hide (tasklist->handle);
}
static void
tasklist_width_changed (GtkSpinButton *sb,
TasklistPlugin *tasklist)
{
tasklist->width = gtk_spin_button_get_value_as_int (sb);
gtk_widget_queue_resize (GTK_WIDGET (tasklist->panel_plugin));
}
static void
tasklist_dialog_response (GtkWidget *dlg,
gint reponse,
TasklistPlugin *tasklist)
{
g_object_set_data (G_OBJECT (tasklist->panel_plugin), I_("dialog"), NULL);
gtk_widget_destroy (dlg);
xfce_panel_plugin_unblock_menu (tasklist->panel_plugin);
tasklist_plugin_write (tasklist);
}
void
tasklist_dialogs_configure (TasklistPlugin *tasklist)
{
GtkWidget *dlg, *mainvbox, *vbox, *frame, *cb,
*hbox, *label, *spin;
xfce_panel_plugin_block_menu (tasklist->panel_plugin);
dlg = xfce_titled_dialog_new_with_buttons (_("Task List"), NULL,
GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_NO_SEPARATOR,
GTK_STOCK_CLOSE, GTK_RESPONSE_OK,
NULL);
gtk_window_set_screen (GTK_WINDOW (dlg), gtk_widget_get_screen (GTK_WIDGET (tasklist->panel_plugin)));
g_object_set_data (G_OBJECT (tasklist->panel_plugin), I_("dialog"), dlg);
gtk_window_set_position (GTK_WINDOW (dlg), GTK_WIN_POS_CENTER);
gtk_window_set_icon_name (GTK_WINDOW (dlg), GTK_STOCK_PROPERTIES);
g_signal_connect (G_OBJECT (dlg), "response",
G_CALLBACK (tasklist_dialog_response), tasklist);
mainvbox = gtk_vbox_new (FALSE, 6);
gtk_container_set_border_width (GTK_CONTAINER (mainvbox), 6);
gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dlg)->vbox), mainvbox,
TRUE, TRUE, 0);
/* Size */
vbox = gtk_vbox_new (FALSE, 6);
frame = xfce_create_framebox_with_content (_("Appearance"), vbox);
gtk_box_pack_start (GTK_BOX (mainvbox), frame, FALSE, FALSE, 0);
hbox = gtk_hbox_new (FALSE, 12);
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
label = gtk_label_new_with_mnemonic (_("_Minimum width:"));
gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
/* an arbitrary max of 4000 should be future proof, right? */
spin = gtk_spin_button_new_with_range (100, 4000, 10);
gtk_box_pack_start (GTK_BOX (hbox), spin, FALSE, FALSE, 0);
gtk_spin_button_set_value (GTK_SPIN_BUTTON (spin), tasklist->width);
gtk_label_set_mnemonic_widget (GTK_LABEL (label), spin);
g_signal_connect (G_OBJECT (spin), "value-changed",
G_CALLBACK (tasklist_width_changed), tasklist);
if (tasklist_using_xinerama (tasklist->panel_plugin))
{
cb = gtk_check_button_new_with_mnemonic (_("Use all available _space"));
gtk_box_pack_start (GTK_BOX (vbox), cb, FALSE, FALSE, 0);
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (cb), tasklist->expand);
g_signal_connect (G_OBJECT (cb), "toggled",
G_CALLBACK (tasklist_expand_toggled), tasklist);
}
cb = gtk_check_button_new_with_mnemonic (_("Use _flat buttons"));
gtk_box_pack_start (GTK_BOX (vbox), cb, FALSE, FALSE, 0);
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (cb), tasklist->flat_buttons);
g_signal_connect (G_OBJECT (cb), "toggled",
G_CALLBACK (tasklist_flat_buttons_toggled), tasklist);
cb = gtk_check_button_new_with_mnemonic (_("Show _handle"));
gtk_box_pack_start (GTK_BOX (vbox), cb, FALSE, FALSE, 0);
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (cb), tasklist->show_handles);
g_signal_connect (G_OBJECT (cb), "toggled",
G_CALLBACK (tasklist_show_handle_toggled), tasklist);
/* Tasks */
vbox = gtk_vbox_new (FALSE, 6);
frame = xfce_create_framebox_with_content (_("Task List"), vbox);
gtk_box_pack_start (GTK_BOX (mainvbox), frame, FALSE, FALSE, 0);
cb = gtk_check_button_new_with_mnemonic (_("Show tasks from _all workspaces"));
gtk_box_pack_start (GTK_BOX (vbox), cb, FALSE, FALSE, 0);
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (cb), tasklist->all_workspaces);
g_signal_connect (G_OBJECT (cb), "toggled",
G_CALLBACK (tasklist_all_workspaces_toggled), tasklist);
cb = gtk_combo_box_new_text ();
gtk_box_pack_start (GTK_BOX (vbox), cb, FALSE, FALSE, 0);
gtk_combo_box_append_text (GTK_COMBO_BOX (cb), _("Never group tasks"));
gtk_combo_box_append_text (GTK_COMBO_BOX (cb), _("Automatically group tasks"));
gtk_combo_box_append_text (GTK_COMBO_BOX (cb), _("Always group tasks"));
/* keep order above in sync with WnckTasklistGroupingType */
gtk_combo_box_set_active (GTK_COMBO_BOX (cb), tasklist->grouping);
g_signal_connect (G_OBJECT (cb), "changed",
G_CALLBACK (tasklist_grouping_changed), tasklist);
gtk_widget_show_all (dlg);
}
Offline
This patch might do it. Not tested at all, not even compile tested. I don't use XFCE.
--- cycle.c.orig 2009-08-04 15:04:17.871189695 -0400 +++ cycle.c 2009-08-04 15:07:21.298206230 -0400 @@ -126,11 +126,13 @@ { TRACE ("Cycle: previous"); c2 = tabwinSelectPrev(passdata->tabwin); + cycling = FALSE; } else if (key == KEY_CYCLE_WINDOWS) { TRACE ("Cycle: next"); c2 = tabwinSelectNext(passdata->tabwin); + cycling = FALSE; } if (c2) {
OK, thanks, I will try it
Offline
When I ran patch it said:
patching file cycle.c
patch unexpectedly ends in middle of line
Hunk #1 succeeded at 126 with fuzz 1.
Is that OK?
Offline
check the file it generated, or post the relevant section.
cheers Phil
Offline
When I ran patch it said:
patching file cycle.c
patch unexpectedly ends in middle of line
Hunk #1 succeeded at 126 with fuzz 1.Is that OK?
That's probably because either you or I didn't paste it with a blank line at the end. Just try it and see.
Offline
I'm trying to patch xfwm4 (xfce's window manager) to cycle windows differently.
Here is the source code for the window cycling, which I got from here: http://www.p0llux.be/xfce/xfce-4.6.1/sr … .1.tar.bz2 (from src/cycle.c)
What will you do when a new XFCE version is released, patch it all over again? When it stops applying you will come here offering prizes again?
I would suggest that you unmap that key binding in XFCE and map it to your own custom program/utility/script which does what you want. You can for example start with using wmctrl.
You need to install an RTFM interface.
Offline
ataraxia: Your patch works except the list pops up every other cycle. It's much better than how it was before though, I'm using it at the moment, thanks.
anrxc: That's a good idea, I could write a bash script that uses "wmctrl -l" to get a list of windows and "wmctrl -ai windowcode" to switch the windows, and it lists the windows in the same order each time so I should be able to cycle. But I want a way of telling which window is currently focused so it can cycle in a consistent manner. There seems to be a command "XGetInputFocus" but when I type it it sais "bash: XGetInputFocus: command not found". "man XGetInputFocus" doesn't help.
How can I find out which window is currently focused?
Thanks.
Last edited by 9nqksfhn (2009-08-05 15:02:57)
Offline
Pages: 1