gboolean prompt_key_event(ObPrompt *self, XEvent *e) { gboolean shift; guint shift_mask, mods; KeySym sym; if (e->type != KeyPress) return FALSE; shift_mask = obt_keyboard_modkey_to_modmask(OBT_KEYBOARD_MODKEY_SHIFT); mods = obt_keyboard_only_modmasks(e->xkey.state); shift = !!(mods & shift_mask); /* only accept shift */ if (mods != 0 && mods != shift_mask) return FALSE; sym = obt_keyboard_keypress_to_keysym(e); if (sym == XK_Escape) prompt_cancel(self); else if (sym == XK_Return || sym == XK_KP_Enter || sym == XK_space) prompt_run_callback(self, self->focus->result); else if (sym == XK_Tab || sym == XK_Left || sym == XK_Right) { gint i; gboolean left; ObPromptElement *oldfocus; left = (sym == XK_Left) || ((sym == XK_Tab) && shift); oldfocus = self->focus; for (i = 0; i < self->n_buttons; ++i) if (self->focus == &self->button[i]) break; i += (left ? -1 : 1); if (i < 0) i = self->n_buttons - 1; else if (i >= self->n_buttons) i = 0; self->focus = &self->button[i]; if (oldfocus != self->focus) render_button(self, oldfocus); render_button(self, self->focus); } return TRUE; }
static void resize_with_keys(KeySym sym, guint state) { gint dw = 0, dh = 0, pdx = 0, pdy = 0, opx, opy, px, py; gint resist = 0; ObDirection dir; /* pick the edge if it needs to move */ if (sym == XK_Right) { dir = OB_DIRECTION_EAST; if (key_resize_edge != OB_DIRECTION_WEST && key_resize_edge != OB_DIRECTION_EAST) { key_resize_edge = OB_DIRECTION_EAST; return; } } else if (sym == XK_Left) { dir = OB_DIRECTION_WEST; if (key_resize_edge != OB_DIRECTION_WEST && key_resize_edge != OB_DIRECTION_EAST) { key_resize_edge = OB_DIRECTION_WEST; return; } } else if (sym == XK_Up) { dir = OB_DIRECTION_NORTH; if (key_resize_edge != OB_DIRECTION_NORTH && key_resize_edge != OB_DIRECTION_SOUTH) { key_resize_edge = OB_DIRECTION_NORTH; return; } } else /* if (sym == XK_Down) */ { dir = OB_DIRECTION_SOUTH; if (key_resize_edge != OB_DIRECTION_NORTH && key_resize_edge != OB_DIRECTION_SOUTH) { key_resize_edge = OB_DIRECTION_SOUTH; return; } } /* shift means jump to edge */ if (state & obt_keyboard_modkey_to_modmask(OBT_KEYBOARD_MODKEY_SHIFT)) { gint x, y, w, h; if (sym == XK_Right) dir = OB_DIRECTION_EAST; else if (sym == XK_Left) dir = OB_DIRECTION_WEST; else if (sym == XK_Down) dir = OB_DIRECTION_SOUTH; else /* if (sym == XK_Up)) */ dir = OB_DIRECTION_NORTH; client_find_resize_directional(moveresize_client, key_resize_edge, key_resize_edge == dir, &x, &y, &w, &h); dw = w - moveresize_client->area.width; dh = h - moveresize_client->area.height; } else { gint distw, disth; /* control means fine grained */ if (moveresize_client->size_inc.width > 1) { distw = moveresize_client->size_inc.width; resist = 1; } else if (state & obt_keyboard_modkey_to_modmask(OBT_KEYBOARD_MODKEY_CONTROL)) { distw = 1; resist = 1; } else { distw = KEY_DIST; resist = KEY_DIST; } if (moveresize_client->size_inc.height > 1) { disth = moveresize_client->size_inc.height; resist = 1; } else if (state & obt_keyboard_modkey_to_modmask(OBT_KEYBOARD_MODKEY_CONTROL)) { disth = 1; resist = 1; } else { disth = KEY_DIST; resist = KEY_DIST; } if (key_resize_edge == OB_DIRECTION_WEST) { if (dir == OB_DIRECTION_WEST) dw = distw; else dw = -distw; } else if (key_resize_edge == OB_DIRECTION_EAST) { if (dir == OB_DIRECTION_EAST) dw = distw; else dw = -distw; } else if (key_resize_edge == OB_DIRECTION_NORTH) { if (dir == OB_DIRECTION_NORTH) dh = disth; else dh = -disth; } else /*if (key_resize_edge == OB_DIRECTION_SOUTH)*/ { if (dir == OB_DIRECTION_SOUTH) dh = disth; else dh = -disth; } } if (moveresize_client->max_horz && (key_resize_edge == OB_DIRECTION_WEST || key_resize_edge == OB_DIRECTION_EAST)) { /* unmax horz */ was_max_horz = TRUE; pre_max_area.x = moveresize_client->pre_max_area.x; pre_max_area.width = moveresize_client->pre_max_area.width; moveresize_client->pre_max_area.x = cur_x; moveresize_client->pre_max_area.width = cur_w; client_maximize(moveresize_client, FALSE, 1); } else if (moveresize_client->max_vert && (key_resize_edge == OB_DIRECTION_NORTH || key_resize_edge == OB_DIRECTION_SOUTH)) { /* unmax vert */ was_max_vert = TRUE; pre_max_area.y = moveresize_client->pre_max_area.y; pre_max_area.height = moveresize_client->pre_max_area.height; moveresize_client->pre_max_area.y = cur_y; moveresize_client->pre_max_area.height = cur_h; client_maximize(moveresize_client, FALSE, 2); } calc_resize(TRUE, resist, &dw, &dh, dir); if (key_resize_edge == OB_DIRECTION_WEST) cur_x -= dw; else if (key_resize_edge == OB_DIRECTION_NORTH) cur_y -= dh; cur_w += dw; cur_h += dh; /* how to move the pointer to keep up with the change */ if (key_resize_edge == OB_DIRECTION_WEST) pdx = -dw; else if (key_resize_edge == OB_DIRECTION_EAST) pdx = dw; else if (key_resize_edge == OB_DIRECTION_NORTH) pdy = -dh; else if (key_resize_edge == OB_DIRECTION_SOUTH) pdy = dh; screen_pointer_pos(&opx, &opy); XWarpPointer(obt_display, None, None, 0, 0, 0, 0, pdx, pdy); /* steal the motion events this causes */ XSync(obt_display, FALSE); { XEvent ce; while (xqueue_remove_local(&ce, xqueue_match_type, GINT_TO_POINTER(MotionNotify))); } screen_pointer_pos(&px, &py); do_resize(); /* because the cursor moves even though the window does not nessesarily (resistance), this adjusts where the cursor thinks it started so that it keeps up with where the window actually is */ start_x += (px - opx) - dw; start_y += (py - opy) - dh; }
static void move_with_keys(KeySym sym, guint state) { gint dx = 0, dy = 0, ox = cur_x, oy = cur_y; gint opx, px, opy, py; gint dist = 0; /* shift means jump to edge */ if (state & obt_keyboard_modkey_to_modmask(OBT_KEYBOARD_MODKEY_SHIFT)) { gint x, y; ObDirection dir; if (sym == XK_Right) dir = OB_DIRECTION_EAST; else if (sym == XK_Left) dir = OB_DIRECTION_WEST; else if (sym == XK_Down) dir = OB_DIRECTION_SOUTH; else /* sym == XK_Up */ dir = OB_DIRECTION_NORTH; client_find_move_directional(moveresize_client, dir, &x, &y); dx = x - moveresize_client->area.x; dy = y - moveresize_client->area.y; } else { /* control means fine grained */ if (state & obt_keyboard_modkey_to_modmask(OBT_KEYBOARD_MODKEY_CONTROL)) { dist = 1; } else dist = KEY_DIST; if (sym == XK_Right) dx = dist; else if (sym == XK_Left) dx = -dist; else if (sym == XK_Down) dy = dist; else /* if (sym == XK_Up) */ dy = -dist; } screen_pointer_pos(&opx, &opy); XWarpPointer(obt_display, None, None, 0, 0, 0, 0, dx, dy); /* steal the motion events this causes */ XSync(obt_display, FALSE); { XEvent ce; while (xqueue_remove_local(&ce, xqueue_match_type, GINT_TO_POINTER(MotionNotify))); } screen_pointer_pos(&px, &py); cur_x += dx; cur_y += dy; do_move(TRUE, dist); /* because the cursor moves even though the window does not nessesarily (resistance), this adjusts where the curor thinks it started so that it keeps up with where the window actually is */ start_x += (px - opx) - (cur_x - ox); start_y += (py - opy) - (cur_y - oy); }