diff -u tilda-0.09.4/debian/changelog tilda-0.09.4/debian/changelog --- tilda-0.09.4/debian/changelog +++ tilda-0.09.4/debian/changelog @@ -1,3 +1,9 @@ +tilda (0.09.4-0ubuntu2) feisty; urgency=low + + * Patch from CVS Tilda to include new keygrabber (lp #63098) + + -- Áron Sisak Tue, 23 Jan 2007 00:43:18 +0100 + tilda (0.09.4-0ubuntu1) feisty; urgency=low * New upstream release. only in patch2: unchanged: --- tilda-0.09.4.orig/src/key_grabber.c +++ tilda-0.09.4/src/key_grabber.c @@ -52,14 +52,9 @@ /* 0 - ypos, 1 - height, 2 - xpos, 3 - width */ static gint posIV[4][16]; -void generate_animation_positions(struct tilda_window_ *tw) +void generate_animation_positions (struct tilda_window_ *tw) { gint i; - -#if DEBUG - printf("generate_animation_positions(): %d\n",cfg_getint (tw->tc, "animation_orientation")); -#endif - gint last_pos_x = cfg_getint (tw->tc, "x_pos"); gint last_pos_y = cfg_getint (tw->tc, "y_pos"); gint last_width = cfg_getint (tw->tc, "max_width"); @@ -88,14 +83,14 @@ case 1: /* bottom->top BOTTOM */ posIV[3][i] = last_width; posIV[2][i] = last_pos_x; - posIV[1][i] = (gint)(posCFV[i]*last_height); + posIV[1][i] = (gint)(posCFV[i]*last_height); posIV[0][i] = (gint)(last_pos_y+last_height-posIV[1][i]); break; case 0: /* top->bottom TOP */ default: posIV[3][i] = last_width; posIV[2][i] = last_pos_x; - posIV[1][i] = (gint)(posCFV[i]*last_height); + posIV[1][i] = (gint)(posCFV[i]*last_height); posIV[0][i] = last_pos_y; } } @@ -103,14 +98,10 @@ static void pull_state (struct tilda_window_ *tw, int state) { -#ifdef DEBUG - puts("pull"); -#endif - gint i; gint w, h; static gint pos=0; - + if (pos == 0 && state != PULL_UP) { gdk_threads_enter(); @@ -145,8 +136,8 @@ } else { - gtk_window_move ((GtkWindow *) tw->window, cfg_getint (tw->tc, "x_pos"), cfg_getint (tw->tc, "y_pos")); - gtk_window_resize ((GtkWindow *) tw->window, cfg_getint (tw->tc, "max_width"), cfg_getint (tw->tc, "max_height")); + //gtk_window_move ((GtkWindow *) tw->window, cfg_getint (tw->tc, "x_pos"), cfg_getint (tw->tc, "y_pos")); + //gtk_window_resize ((GtkWindow *) tw->window, cfg_getint (tw->tc, "max_width"), cfg_getint (tw->tc, "max_height")); gdk_flush(); gdk_threads_leave(); } @@ -180,7 +171,7 @@ } else { - gtk_window_resize ((GtkWindow *) tw->window, cfg_getint (tw->tc, "min_width"), cfg_getint (tw->tc, "min_height")); + //gtk_window_resize ((GtkWindow *) tw->window, cfg_getint (tw->tc, "min_width"), cfg_getint (tw->tc, "min_height")); gdk_flush(); gdk_threads_leave(); } @@ -200,53 +191,114 @@ pull_state (tw, PULL_TOGGLE); } -static void key_grab (tilda_window *tw) +static int parse_key (tilda_window *tw, gchar *key_str, KeySym *key_ret) { -#ifdef DEBUG - puts("key_grab"); -#endif - - XModifierKeymap *modmap; gchar tmp_key[32]; - unsigned int numlockmask = 0; - unsigned int modmask = 0; - gint i, j; + KeySym key = NoSymbol; + gchar *key_ptr = key_str; - g_strlcpy (tmp_key, cfg_getstr (tw->tc, "key"), sizeof (tmp_key)); + /* Exceptions to "normal" keys go here, such as the "grave" key */ + if (g_strrstr (key_str, "`")) { key_ptr = "grave"; } - /* Key grabbing stuff taken from yeahconsole who took it from evilwm */ - modmap = XGetModifierMapping(dpy); - for (i = 0; i < 8; i++) + /* Now, try to have XStringToKeysym() parse it */ + key = XStringToKeysym (key_ptr); + + /* Check for failure */ + if (key == NoSymbol) { - for (j = 0; j < modmap->max_keypermod; j++) + /* Use default */ + fprintf (stderr, "Bad key: \"%s\" not recognized. Using default of F%d " + " (leaving your modifiers as-is).\n", key_ptr, tw->instance+1); + g_snprintf (tmp_key, sizeof(tmp_key), "F%d", tw->instance+1); + + /* Re-parse the default key */ + key = XStringToKeysym (tmp_key); + + if (key == NoSymbol) { - if (modmap->modifiermap[i * modmap->max_keypermod + j] == XKeysymToKeycode(dpy, XK_Num_Lock)) - { - numlockmask = (1 << i); - } + fprintf (stderr, "Using the default failed, bailing out...\n"); + exit (EXIT_FAILURE); } } - XFreeModifiermap(modmap); + *key_ret = key; - if (strstr(tmp_key, "Control")) - modmask = modmask | ControlMask; + return 0; +} + +static int parse_keybinding (tilda_window *tw, guint *modmask_ret, KeySym *key_ret) +{ + guint modmask = 0; + KeySym key = NoSymbol; + gchar *key_str; + gchar **key_split; + gint i; + + key_str = g_strdup (cfg_getstr (tw->tc, "key")); + key_str = g_strstrip (key_str); + key_split = g_strsplit (key_str, "+", 3); + + for (i=0; imax_keypermod; j++) + if (modmap->modifiermap[i * modmap->max_keypermod + j] == XKeysymToKeycode(dpy, XK_Num_Lock)) + numlockmask = (1 << i); - if (strtok(tmp_key, "+")) - key = XStringToKeysym(strtok(NULL, "+")); + XFreeModifiermap(modmap); + /* Parse the keybinding from the config file. + * + * NOTE: the variable "key" is global, so it can be used here and + * in the wait_for_signal() function below. + */ + parse_keybinding (tw, &modmask, &key); + + /* Bind the key(s) appropriately. + * + * NOTE: If you're getting BadAccess errors from here in the code, then + * something in your environment has already bound this key! Use a different + * keybinding. + * + * Unfortunately, we can't report this to the user, since X kills the program + * automatically when it recieves a BadAccess error. :( + */ XGrabKey(dpy, XKeysymToKeycode(dpy, key), modmask, root, True, GrabModeAsync, GrabModeAsync); XGrabKey(dpy, XKeysymToKeycode(dpy, key), LockMask | modmask, root, True, GrabModeAsync, GrabModeAsync); @@ -255,6 +307,54 @@ XGrabKey(dpy, XKeysymToKeycode(dpy, key), numlockmask | modmask, root, True, GrabModeAsync, GrabModeAsync); XGrabKey(dpy, XKeysymToKeycode(dpy, key), numlockmask | LockMask | modmask, root, True, GrabModeAsync, GrabModeAsync); } + + /* Make absolutely sure that these are grabbed at this point. */ + XFlush (dpy); +} + +/* + * This will "ungrab" the key that is currently being used by the application + * to toggle the window state. + * + * This should be used in the wizard just before the key grabber button is + * pressed, so that the user can press the same key that they are using. + */ +void key_ungrab (tilda_window *tw) +{ + XModifierKeymap *modmap; + guint numlockmask = 0; + guint modmask = 0; + gint i, j; + + /* Key grabbing stuff taken from yeahconsole who took it from evilwm */ + modmap = XGetModifierMapping(dpy); + + for (i = 0; i < 8; i++) + for (j = 0; j < modmap->max_keypermod; j++) + if (modmap->modifiermap[i * modmap->max_keypermod + j] == XKeysymToKeycode(dpy, XK_Num_Lock)) + numlockmask = (1 << i); + + XFreeModifiermap(modmap); + + /* Parse the keybinding from the config file. + * + * NOTE: the variable "key" is global, so it can be used here and + * in the wait_for_signal() function below. + */ + parse_keybinding (tw, &modmask, &key); + + /* Unbind the key(s) appropriately. */ + XUngrabKey(dpy, XKeysymToKeycode(dpy, key), modmask, root); + XUngrabKey(dpy, XKeysymToKeycode(dpy, key), LockMask | modmask, root); + + if (numlockmask) + { + XUngrabKey(dpy, XKeysymToKeycode(dpy, key), numlockmask | modmask, root); + XUngrabKey(dpy, XKeysymToKeycode(dpy, key), numlockmask | LockMask | modmask, root); + } + + /* Make absolutely sure that the keys are unbound by now */ + XFlush (dpy); } void *wait_for_signal (tilda_window *tw) @@ -263,22 +363,25 @@ XEvent event; if (!(dpy = XOpenDisplay(NULL))) - fprintf (stderr, "Shit -- can't open Display %s", XDisplayName(NULL)); + { + fprintf (stderr, "Cannot open Display %s", XDisplayName(NULL)); + exit (EXIT_FAILURE); + } screen = DefaultScreen(dpy); root = RootWindow(dpy, screen); - display_width = DisplayWidth(dpy, screen); + display_width = DisplayWidth(dpy, screen); display_height = DisplayHeight(dpy, screen); - + key_grab (tw); if (cfg_getbool (tw->tc, "hidden")) { /* - * Fixes bug that causes Tilda to eat up 100% of CPU + * Fixes bug that causes Tilda to eat up 100% of CPU * if set to stay hidden when started - */ + */ pull_state(tw, PULL_DOWN); pull_state(tw, PULL_UP); }