2001-06-06 00:47:37 -04:00
|
|
|
/* Metacity Keybindings */
|
|
|
|
|
|
|
|
/*
|
2002-04-28 00:52:26 -04:00
|
|
|
* Copyright (C) 2001 Havoc Pennington, 2002 Red Hat Inc.
|
2001-06-06 00:47:37 -04:00
|
|
|
*
|
|
|
|
* 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 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
|
|
|
|
* 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., 59 Temple Place - Suite 330, Boston, MA
|
|
|
|
* 02111-1307, USA.
|
|
|
|
*/
|
|
|
|
|
2001-12-09 17:41:12 -05:00
|
|
|
#include <config.h>
|
2001-06-06 00:47:37 -04:00
|
|
|
#include "keybindings.h"
|
|
|
|
#include "workspace.h"
|
|
|
|
#include "errors.h"
|
2001-06-23 01:49:35 -04:00
|
|
|
#include "ui.h"
|
|
|
|
#include "frame.h"
|
2001-07-12 01:53:56 -04:00
|
|
|
#include "place.h"
|
2002-04-28 00:52:26 -04:00
|
|
|
#include "prefs.h"
|
2001-06-06 00:47:37 -04:00
|
|
|
|
|
|
|
#include <X11/keysym.h>
|
2002-04-28 00:52:26 -04:00
|
|
|
#include <string.h>
|
2001-06-06 00:47:37 -04:00
|
|
|
|
2002-02-08 01:01:58 -05:00
|
|
|
static gboolean all_bindings_disabled = FALSE;
|
2001-06-06 00:47:37 -04:00
|
|
|
|
2002-04-28 00:52:26 -04:00
|
|
|
typedef void (* MetaKeyHandlerFunc) (MetaDisplay *display,
|
2002-10-16 16:12:24 -04:00
|
|
|
MetaScreen *screen,
|
2002-04-28 00:52:26 -04:00
|
|
|
MetaWindow *window,
|
|
|
|
XEvent *event,
|
|
|
|
MetaKeyBinding *binding);
|
|
|
|
|
|
|
|
static void handle_activate_workspace (MetaDisplay *display,
|
2002-10-16 16:12:24 -04:00
|
|
|
MetaScreen *screen,
|
2002-04-28 00:52:26 -04:00
|
|
|
MetaWindow *window,
|
|
|
|
XEvent *event,
|
|
|
|
MetaKeyBinding *binding);
|
|
|
|
static void handle_activate_menu (MetaDisplay *display,
|
2002-10-16 16:12:24 -04:00
|
|
|
MetaScreen *screen,
|
2002-04-28 00:52:26 -04:00
|
|
|
MetaWindow *window,
|
|
|
|
XEvent *event,
|
|
|
|
MetaKeyBinding *binding);
|
|
|
|
static void handle_tab_forward (MetaDisplay *display,
|
2002-10-16 16:12:24 -04:00
|
|
|
MetaScreen *screen,
|
2002-04-28 00:52:26 -04:00
|
|
|
MetaWindow *window,
|
|
|
|
XEvent *event,
|
|
|
|
MetaKeyBinding *binding);
|
2002-10-18 18:19:05 -04:00
|
|
|
static void handle_tab_backward (MetaDisplay *display,
|
|
|
|
MetaScreen *screen,
|
|
|
|
MetaWindow *window,
|
|
|
|
XEvent *event,
|
|
|
|
MetaKeyBinding *binding);
|
2002-07-06 12:50:48 -04:00
|
|
|
static void handle_cycle_forward (MetaDisplay *display,
|
2002-10-16 16:12:24 -04:00
|
|
|
MetaScreen *screen,
|
2002-04-28 00:52:26 -04:00
|
|
|
MetaWindow *window,
|
|
|
|
XEvent *event,
|
|
|
|
MetaKeyBinding *binding);
|
2002-10-18 18:19:05 -04:00
|
|
|
static void handle_cycle_backward (MetaDisplay *display,
|
|
|
|
MetaScreen *screen,
|
|
|
|
MetaWindow *window,
|
|
|
|
XEvent *event,
|
|
|
|
MetaKeyBinding *binding);
|
2002-04-28 00:52:26 -04:00
|
|
|
static void handle_toggle_fullscreen (MetaDisplay *display,
|
2002-10-16 16:12:24 -04:00
|
|
|
MetaScreen *screen,
|
2002-04-28 00:52:26 -04:00
|
|
|
MetaWindow *window,
|
|
|
|
XEvent *event,
|
|
|
|
MetaKeyBinding *binding);
|
|
|
|
static void handle_toggle_desktop (MetaDisplay *display,
|
2002-10-16 16:12:24 -04:00
|
|
|
MetaScreen *screen,
|
2002-04-28 00:52:26 -04:00
|
|
|
MetaWindow *window,
|
|
|
|
XEvent *event,
|
|
|
|
MetaKeyBinding *binding);
|
|
|
|
static void handle_toggle_maximize (MetaDisplay *display,
|
2002-10-16 16:12:24 -04:00
|
|
|
MetaScreen *screen,
|
2002-04-28 00:52:26 -04:00
|
|
|
MetaWindow *window,
|
|
|
|
XEvent *event,
|
|
|
|
MetaKeyBinding *binding);
|
2002-08-21 02:47:16 -04:00
|
|
|
static void handle_maximize (MetaDisplay *display,
|
2002-10-16 16:12:24 -04:00
|
|
|
MetaScreen *screen,
|
2002-08-21 02:47:16 -04:00
|
|
|
MetaWindow *window,
|
|
|
|
XEvent *event,
|
|
|
|
MetaKeyBinding *binding);
|
|
|
|
static void handle_unmaximize (MetaDisplay *display,
|
2002-10-16 16:12:24 -04:00
|
|
|
MetaScreen *screen,
|
2002-08-21 02:47:16 -04:00
|
|
|
MetaWindow *window,
|
|
|
|
XEvent *event,
|
|
|
|
MetaKeyBinding *binding);
|
2002-04-28 00:52:26 -04:00
|
|
|
static void handle_toggle_shade (MetaDisplay *display,
|
2002-10-16 16:12:24 -04:00
|
|
|
MetaScreen *screen,
|
2002-04-28 00:52:26 -04:00
|
|
|
MetaWindow *window,
|
|
|
|
XEvent *event,
|
|
|
|
MetaKeyBinding *binding);
|
|
|
|
static void handle_close_window (MetaDisplay *display,
|
2002-10-16 16:12:24 -04:00
|
|
|
MetaScreen *screen,
|
2002-04-28 00:52:26 -04:00
|
|
|
MetaWindow *window,
|
|
|
|
XEvent *event,
|
|
|
|
MetaKeyBinding *binding);
|
2002-05-24 22:30:00 -04:00
|
|
|
static void handle_minimize_window (MetaDisplay *display,
|
2002-10-16 16:12:24 -04:00
|
|
|
MetaScreen *screen,
|
2002-05-24 22:30:00 -04:00
|
|
|
MetaWindow *window,
|
|
|
|
XEvent *event,
|
|
|
|
MetaKeyBinding *binding);
|
2002-04-28 00:52:26 -04:00
|
|
|
static void handle_begin_move (MetaDisplay *display,
|
2002-10-16 16:12:24 -04:00
|
|
|
MetaScreen *screen,
|
2002-04-28 00:52:26 -04:00
|
|
|
MetaWindow *window,
|
|
|
|
XEvent *event,
|
|
|
|
MetaKeyBinding *binding);
|
|
|
|
static void handle_begin_resize (MetaDisplay *display,
|
2002-10-16 16:12:24 -04:00
|
|
|
MetaScreen *screen,
|
2002-04-28 00:52:26 -04:00
|
|
|
MetaWindow *window,
|
|
|
|
XEvent *event,
|
|
|
|
MetaKeyBinding *binding);
|
|
|
|
static void handle_toggle_sticky (MetaDisplay *display,
|
2002-10-16 16:12:24 -04:00
|
|
|
MetaScreen *screen,
|
2002-04-28 00:52:26 -04:00
|
|
|
MetaWindow *window,
|
|
|
|
XEvent *event,
|
|
|
|
MetaKeyBinding *binding);
|
|
|
|
static void handle_move_to_workspace (MetaDisplay *display,
|
2002-10-16 16:12:24 -04:00
|
|
|
MetaScreen *screen,
|
2002-04-28 00:52:26 -04:00
|
|
|
MetaWindow *window,
|
|
|
|
XEvent *event,
|
|
|
|
MetaKeyBinding *binding);
|
2002-06-09 00:04:19 -04:00
|
|
|
static void handle_workspace_switch (MetaDisplay *display,
|
2002-10-16 16:12:24 -04:00
|
|
|
MetaScreen *screen,
|
2002-06-08 23:44:16 -04:00
|
|
|
MetaWindow *window,
|
|
|
|
XEvent *event,
|
|
|
|
MetaKeyBinding *binding);
|
2002-05-28 23:11:24 -04:00
|
|
|
static void handle_raise_or_lower (MetaDisplay *display,
|
2002-10-16 16:12:24 -04:00
|
|
|
MetaScreen *screen,
|
2002-05-28 23:11:24 -04:00
|
|
|
MetaWindow *window,
|
|
|
|
XEvent *event,
|
|
|
|
MetaKeyBinding *binding);
|
2002-08-15 01:14:49 -04:00
|
|
|
static void handle_raise (MetaDisplay *display,
|
2002-10-16 16:12:24 -04:00
|
|
|
MetaScreen *screen,
|
2002-08-15 01:14:49 -04:00
|
|
|
MetaWindow *window,
|
|
|
|
XEvent *event,
|
|
|
|
MetaKeyBinding *binding);
|
|
|
|
static void handle_lower (MetaDisplay *display,
|
2002-10-16 16:12:24 -04:00
|
|
|
MetaScreen *screen,
|
2002-08-15 01:14:49 -04:00
|
|
|
MetaWindow *window,
|
|
|
|
XEvent *event,
|
|
|
|
MetaKeyBinding *binding);
|
2002-07-11 00:10:44 -04:00
|
|
|
static void handle_run_command (MetaDisplay *display,
|
2002-10-16 16:12:24 -04:00
|
|
|
MetaScreen *screen,
|
2002-07-11 00:10:44 -04:00
|
|
|
MetaWindow *window,
|
|
|
|
XEvent *event,
|
|
|
|
MetaKeyBinding *binding);
|
2002-12-08 16:09:05 -05:00
|
|
|
static void handle_maximize_vert (MetaDisplay *display,
|
|
|
|
MetaScreen *screen,
|
|
|
|
MetaWindow *window,
|
|
|
|
XEvent *event,
|
|
|
|
MetaKeyBinding *binding);
|
|
|
|
static void handle_maximize_horiz (MetaDisplay *display,
|
|
|
|
MetaScreen *screen,
|
|
|
|
MetaWindow *window,
|
|
|
|
XEvent *event,
|
|
|
|
MetaKeyBinding *binding);
|
2002-01-10 22:31:14 -05:00
|
|
|
|
|
|
|
/* debug */
|
|
|
|
static void handle_spew_mark (MetaDisplay *display,
|
2002-10-16 16:12:24 -04:00
|
|
|
MetaScreen *screen,
|
2002-01-10 22:31:14 -05:00
|
|
|
MetaWindow *window,
|
|
|
|
XEvent *event,
|
2002-04-28 00:52:26 -04:00
|
|
|
MetaKeyBinding *binding);
|
2002-01-10 22:31:14 -05:00
|
|
|
|
2001-08-19 14:09:10 -04:00
|
|
|
static gboolean process_keyboard_move_grab (MetaDisplay *display,
|
2002-10-16 16:12:24 -04:00
|
|
|
MetaScreen *screen,
|
2001-08-19 14:09:10 -04:00
|
|
|
MetaWindow *window,
|
|
|
|
XEvent *event,
|
|
|
|
KeySym keysym);
|
|
|
|
|
2002-06-19 00:12:49 -04:00
|
|
|
static gboolean process_keyboard_resize_grab (MetaDisplay *display,
|
2002-10-16 16:12:24 -04:00
|
|
|
MetaScreen *screen,
|
2002-06-19 00:12:49 -04:00
|
|
|
MetaWindow *window,
|
|
|
|
XEvent *event,
|
|
|
|
KeySym keysym);
|
|
|
|
|
2001-08-19 14:09:10 -04:00
|
|
|
static gboolean process_tab_grab (MetaDisplay *display,
|
2002-10-16 16:12:24 -04:00
|
|
|
MetaScreen *screen,
|
2001-08-19 14:09:10 -04:00
|
|
|
XEvent *event,
|
|
|
|
KeySym keysym);
|
2001-06-06 00:47:37 -04:00
|
|
|
|
2002-06-09 00:04:19 -04:00
|
|
|
static gboolean process_workspace_switch_grab (MetaDisplay *display,
|
2002-10-16 16:12:24 -04:00
|
|
|
MetaScreen *screen,
|
2002-06-09 00:04:19 -04:00
|
|
|
XEvent *event,
|
|
|
|
KeySym keysym);
|
2002-06-08 23:44:16 -04:00
|
|
|
|
2002-04-28 00:52:26 -04:00
|
|
|
static void regrab_screen_bindings (MetaDisplay *display);
|
|
|
|
static void regrab_window_bindings (MetaDisplay *display);
|
|
|
|
|
|
|
|
typedef struct
|
|
|
|
{
|
|
|
|
const char *name;
|
|
|
|
MetaKeyHandlerFunc func;
|
|
|
|
void *data;
|
|
|
|
} MetaKeyHandler;
|
2001-06-06 00:47:37 -04:00
|
|
|
|
|
|
|
struct _MetaKeyBinding
|
|
|
|
{
|
2002-04-28 00:52:26 -04:00
|
|
|
const char *name;
|
2001-06-06 00:47:37 -04:00
|
|
|
KeySym keysym;
|
2002-04-28 00:52:26 -04:00
|
|
|
unsigned int mask;
|
2001-06-06 00:47:37 -04:00
|
|
|
int keycode;
|
2002-07-13 23:16:41 -04:00
|
|
|
MetaVirtualModifier modifiers;
|
2002-04-28 00:52:26 -04:00
|
|
|
const MetaKeyHandler *handler;
|
2001-06-06 00:47:37 -04:00
|
|
|
};
|
|
|
|
|
2002-04-28 00:52:26 -04:00
|
|
|
static const MetaKeyHandler screen_handlers[] = {
|
|
|
|
{ META_KEYBINDING_WORKSPACE_1, handle_activate_workspace,
|
|
|
|
GINT_TO_POINTER (0) },
|
|
|
|
{ META_KEYBINDING_WORKSPACE_2, handle_activate_workspace,
|
|
|
|
GINT_TO_POINTER (1) },
|
|
|
|
{ META_KEYBINDING_WORKSPACE_3, handle_activate_workspace,
|
|
|
|
GINT_TO_POINTER (2) },
|
|
|
|
{ META_KEYBINDING_WORKSPACE_4, handle_activate_workspace,
|
|
|
|
GINT_TO_POINTER (3) },
|
|
|
|
{ META_KEYBINDING_WORKSPACE_5, handle_activate_workspace,
|
|
|
|
GINT_TO_POINTER (4) },
|
|
|
|
{ META_KEYBINDING_WORKSPACE_6, handle_activate_workspace,
|
|
|
|
GINT_TO_POINTER (5) },
|
|
|
|
{ META_KEYBINDING_WORKSPACE_7, handle_activate_workspace,
|
|
|
|
GINT_TO_POINTER (6) },
|
|
|
|
{ META_KEYBINDING_WORKSPACE_8, handle_activate_workspace,
|
|
|
|
GINT_TO_POINTER (7) },
|
|
|
|
{ META_KEYBINDING_WORKSPACE_9, handle_activate_workspace,
|
|
|
|
GINT_TO_POINTER (8) },
|
|
|
|
{ META_KEYBINDING_WORKSPACE_10, handle_activate_workspace,
|
|
|
|
GINT_TO_POINTER (9) },
|
|
|
|
{ META_KEYBINDING_WORKSPACE_11, handle_activate_workspace,
|
|
|
|
GINT_TO_POINTER (10) },
|
|
|
|
{ META_KEYBINDING_WORKSPACE_12, handle_activate_workspace,
|
|
|
|
GINT_TO_POINTER (11) },
|
2002-06-09 00:04:19 -04:00
|
|
|
{ META_KEYBINDING_WORKSPACE_LEFT, handle_workspace_switch,
|
2002-04-28 00:52:26 -04:00
|
|
|
GINT_TO_POINTER (META_MOTION_LEFT) },
|
2002-06-09 00:04:19 -04:00
|
|
|
{ META_KEYBINDING_WORKSPACE_RIGHT, handle_workspace_switch,
|
2002-04-28 00:52:26 -04:00
|
|
|
GINT_TO_POINTER (META_MOTION_RIGHT) },
|
2002-06-09 00:04:19 -04:00
|
|
|
{ META_KEYBINDING_WORKSPACE_UP, handle_workspace_switch,
|
2002-04-28 00:52:26 -04:00
|
|
|
GINT_TO_POINTER (META_MOTION_UP) },
|
2002-06-09 00:04:19 -04:00
|
|
|
{ META_KEYBINDING_WORKSPACE_DOWN, handle_workspace_switch,
|
2002-04-28 00:52:26 -04:00
|
|
|
GINT_TO_POINTER (META_MOTION_DOWN) },
|
|
|
|
{ META_KEYBINDING_SWITCH_WINDOWS, handle_tab_forward,
|
|
|
|
GINT_TO_POINTER (META_TAB_LIST_NORMAL) },
|
2002-10-18 18:19:05 -04:00
|
|
|
{ META_KEYBINDING_SWITCH_WINDOWS_BACKWARD, handle_tab_backward,
|
|
|
|
GINT_TO_POINTER (META_TAB_LIST_NORMAL) },
|
2002-04-28 00:52:26 -04:00
|
|
|
{ META_KEYBINDING_SWITCH_PANELS, handle_tab_forward,
|
|
|
|
GINT_TO_POINTER (META_TAB_LIST_DOCKS) },
|
2002-10-18 18:19:05 -04:00
|
|
|
{ META_KEYBINDING_SWITCH_PANELS_BACKWARD, handle_tab_backward,
|
|
|
|
GINT_TO_POINTER (META_TAB_LIST_DOCKS) },
|
2002-07-06 12:50:48 -04:00
|
|
|
{ META_KEYBINDING_CYCLE_WINDOWS, handle_cycle_forward,
|
|
|
|
GINT_TO_POINTER (META_TAB_LIST_NORMAL) },
|
2002-10-18 18:19:05 -04:00
|
|
|
{ META_KEYBINDING_CYCLE_WINDOWS_BACKWARD, handle_cycle_backward,
|
|
|
|
GINT_TO_POINTER (META_TAB_LIST_NORMAL) },
|
2002-07-06 12:50:48 -04:00
|
|
|
{ META_KEYBINDING_CYCLE_PANELS, handle_cycle_forward,
|
|
|
|
GINT_TO_POINTER (META_TAB_LIST_DOCKS) },
|
2002-10-18 18:19:05 -04:00
|
|
|
{ META_KEYBINDING_CYCLE_PANELS_BACKWARD, handle_cycle_backward,
|
|
|
|
GINT_TO_POINTER (META_TAB_LIST_DOCKS) },
|
2002-04-28 00:52:26 -04:00
|
|
|
{ META_KEYBINDING_SHOW_DESKTOP, handle_toggle_desktop,
|
|
|
|
NULL },
|
2002-07-11 00:10:44 -04:00
|
|
|
{ META_KEYBINDING_COMMAND_1, handle_run_command,
|
|
|
|
GINT_TO_POINTER (0) },
|
|
|
|
{ META_KEYBINDING_COMMAND_2, handle_run_command,
|
|
|
|
GINT_TO_POINTER (1) },
|
|
|
|
{ META_KEYBINDING_COMMAND_3, handle_run_command,
|
|
|
|
GINT_TO_POINTER (2) },
|
|
|
|
{ META_KEYBINDING_COMMAND_4, handle_run_command,
|
|
|
|
GINT_TO_POINTER (3) },
|
|
|
|
{ META_KEYBINDING_COMMAND_5, handle_run_command,
|
|
|
|
GINT_TO_POINTER (4) },
|
|
|
|
{ META_KEYBINDING_COMMAND_6, handle_run_command,
|
|
|
|
GINT_TO_POINTER (5) },
|
|
|
|
{ META_KEYBINDING_COMMAND_7, handle_run_command,
|
|
|
|
GINT_TO_POINTER (6) },
|
|
|
|
{ META_KEYBINDING_COMMAND_8, handle_run_command,
|
|
|
|
GINT_TO_POINTER (7) },
|
|
|
|
{ META_KEYBINDING_COMMAND_9, handle_run_command,
|
|
|
|
GINT_TO_POINTER (8) },
|
|
|
|
{ META_KEYBINDING_COMMAND_10, handle_run_command,
|
|
|
|
GINT_TO_POINTER (9) },
|
|
|
|
{ META_KEYBINDING_COMMAND_11, handle_run_command,
|
|
|
|
GINT_TO_POINTER (10) },
|
|
|
|
{ META_KEYBINDING_COMMAND_12, handle_run_command,
|
|
|
|
GINT_TO_POINTER (11) },
|
2002-04-28 00:52:26 -04:00
|
|
|
{ NULL, NULL, NULL }
|
2002-01-10 22:31:14 -05:00
|
|
|
};
|
|
|
|
|
2002-04-28 00:52:26 -04:00
|
|
|
static const MetaKeyHandler window_handlers[] = {
|
|
|
|
{ META_KEYBINDING_WINDOW_MENU, handle_activate_menu, NULL },
|
|
|
|
{ META_KEYBINDING_TOGGLE_FULLSCREEN, handle_toggle_fullscreen, NULL },
|
|
|
|
{ META_KEYBINDING_TOGGLE_MAXIMIZE, handle_toggle_maximize, NULL },
|
2002-08-21 02:47:16 -04:00
|
|
|
{ META_KEYBINDING_MAXIMIZE, handle_maximize, NULL },
|
|
|
|
{ META_KEYBINDING_UNMAXIMIZE, handle_unmaximize, NULL },
|
2002-04-28 00:52:26 -04:00
|
|
|
{ META_KEYBINDING_TOGGLE_SHADE, handle_toggle_shade, NULL },
|
|
|
|
{ META_KEYBINDING_CLOSE, handle_close_window, NULL },
|
2002-05-24 22:30:00 -04:00
|
|
|
{ META_KEYBINDING_MINIMIZE, handle_minimize_window, NULL },
|
2002-04-28 00:52:26 -04:00
|
|
|
{ META_KEYBINDING_BEGIN_MOVE, handle_begin_move, },
|
|
|
|
{ META_KEYBINDING_BEGIN_RESIZE, handle_begin_resize, },
|
|
|
|
{ META_KEYBINDING_TOGGLE_STICKY, handle_toggle_sticky, },
|
|
|
|
{ META_KEYBINDING_MOVE_WORKSPACE_1, handle_move_to_workspace,
|
|
|
|
GINT_TO_POINTER (0) },
|
|
|
|
{ META_KEYBINDING_MOVE_WORKSPACE_2, handle_move_to_workspace,
|
|
|
|
GINT_TO_POINTER (1) },
|
|
|
|
{ META_KEYBINDING_MOVE_WORKSPACE_3, handle_move_to_workspace,
|
|
|
|
GINT_TO_POINTER (2) },
|
|
|
|
{ META_KEYBINDING_MOVE_WORKSPACE_4, handle_move_to_workspace,
|
|
|
|
GINT_TO_POINTER (3) },
|
|
|
|
{ META_KEYBINDING_MOVE_WORKSPACE_5, handle_move_to_workspace,
|
|
|
|
GINT_TO_POINTER (4) },
|
|
|
|
{ META_KEYBINDING_MOVE_WORKSPACE_6, handle_move_to_workspace,
|
|
|
|
GINT_TO_POINTER (5) },
|
|
|
|
{ META_KEYBINDING_MOVE_WORKSPACE_7, handle_move_to_workspace,
|
|
|
|
GINT_TO_POINTER (6) },
|
|
|
|
{ META_KEYBINDING_MOVE_WORKSPACE_8, handle_move_to_workspace,
|
|
|
|
GINT_TO_POINTER (7) },
|
|
|
|
{ META_KEYBINDING_MOVE_WORKSPACE_9, handle_move_to_workspace,
|
|
|
|
GINT_TO_POINTER (8) },
|
|
|
|
{ META_KEYBINDING_MOVE_WORKSPACE_10, handle_move_to_workspace,
|
|
|
|
GINT_TO_POINTER (9) },
|
|
|
|
{ META_KEYBINDING_MOVE_WORKSPACE_11, handle_move_to_workspace,
|
|
|
|
GINT_TO_POINTER (10) },
|
|
|
|
{ META_KEYBINDING_MOVE_WORKSPACE_12, handle_move_to_workspace,
|
|
|
|
GINT_TO_POINTER (11) },
|
|
|
|
{ META_KEYBINDING_MOVE_WORKSPACE_LEFT, handle_move_to_workspace,
|
|
|
|
GINT_TO_POINTER (META_MOTION_LEFT) },
|
|
|
|
{ META_KEYBINDING_MOVE_WORKSPACE_RIGHT, handle_move_to_workspace,
|
|
|
|
GINT_TO_POINTER (META_MOTION_RIGHT) },
|
|
|
|
{ META_KEYBINDING_MOVE_WORKSPACE_UP, handle_move_to_workspace,
|
|
|
|
GINT_TO_POINTER (META_MOTION_UP) },
|
|
|
|
{ META_KEYBINDING_MOVE_WORKSPACE_DOWN, handle_move_to_workspace,
|
|
|
|
GINT_TO_POINTER (META_MOTION_DOWN) },
|
2002-05-28 23:11:24 -04:00
|
|
|
{ META_KEYBINDING_RAISE_OR_LOWER, handle_raise_or_lower, NULL},
|
2002-08-15 01:14:49 -04:00
|
|
|
{ META_KEYBINDING_RAISE, handle_raise, NULL},
|
|
|
|
{ META_KEYBINDING_LOWER, handle_lower, NULL},
|
2002-12-08 16:09:05 -05:00
|
|
|
{ META_KEYBINDING_MAXIMIZE_VERTICALLY, handle_maximize_vert, NULL },
|
|
|
|
{ META_KEYBINDING_MAXIMIZE_HORIZONTALLY, handle_maximize_horiz, NULL },
|
2002-04-28 00:52:26 -04:00
|
|
|
{ NULL, NULL, NULL }
|
2001-06-23 01:49:35 -04:00
|
|
|
};
|
|
|
|
|
|
|
|
static void
|
2002-04-28 00:52:26 -04:00
|
|
|
reload_keymap (MetaDisplay *display)
|
|
|
|
{
|
|
|
|
if (display->keymap)
|
|
|
|
meta_XFree (display->keymap);
|
|
|
|
|
|
|
|
display->keymap = XGetKeyboardMapping (display->xdisplay,
|
|
|
|
display->min_keycode,
|
|
|
|
display->max_keycode -
|
|
|
|
display->min_keycode,
|
|
|
|
&display->keysyms_per_keycode);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
reload_modmap (MetaDisplay *display)
|
2001-06-06 00:47:37 -04:00
|
|
|
{
|
2002-04-28 00:52:26 -04:00
|
|
|
XModifierKeymap *modmap;
|
|
|
|
int map_size;
|
2001-06-06 00:47:37 -04:00
|
|
|
int i;
|
2002-04-28 00:52:26 -04:00
|
|
|
|
|
|
|
if (display->modmap)
|
|
|
|
XFreeModifiermap (display->modmap);
|
2001-06-06 00:47:37 -04:00
|
|
|
|
2002-04-28 00:52:26 -04:00
|
|
|
modmap = XGetModifierMapping (display->xdisplay);
|
|
|
|
display->modmap = modmap;
|
|
|
|
|
|
|
|
display->ignored_modifier_mask = 0;
|
|
|
|
|
|
|
|
/* Multiple bits may get set in each of these */
|
|
|
|
display->num_lock_mask = 0;
|
|
|
|
display->scroll_lock_mask = 0;
|
2002-07-13 23:16:41 -04:00
|
|
|
display->meta_mask = 0;
|
|
|
|
display->hyper_mask = 0;
|
|
|
|
display->super_mask = 0;
|
2002-04-28 00:52:26 -04:00
|
|
|
|
|
|
|
/* there are 8 modifiers, and the first 3 are shift, shift lock,
|
|
|
|
* and control
|
|
|
|
*/
|
|
|
|
map_size = 8 * modmap->max_keypermod;
|
|
|
|
i = 3 * modmap->max_keypermod;
|
|
|
|
while (i < map_size)
|
2001-06-06 00:47:37 -04:00
|
|
|
{
|
2002-04-28 00:52:26 -04:00
|
|
|
/* get the key code at this point in the map,
|
|
|
|
* see if its keysym is one we're interested in
|
|
|
|
*/
|
|
|
|
int keycode = modmap->modifiermap[i];
|
|
|
|
|
|
|
|
if (keycode >= display->min_keycode &&
|
|
|
|
keycode <= display->max_keycode)
|
|
|
|
{
|
|
|
|
int j = 0;
|
|
|
|
KeySym *syms = display->keymap +
|
|
|
|
(keycode - display->min_keycode) * display->keysyms_per_keycode;
|
|
|
|
|
|
|
|
while (j < display->keysyms_per_keycode)
|
|
|
|
{
|
2002-06-15 23:03:08 -04:00
|
|
|
if (syms[j] != 0)
|
|
|
|
{
|
|
|
|
const char *str;
|
|
|
|
|
|
|
|
str = XKeysymToString (syms[j]);
|
|
|
|
meta_topic (META_DEBUG_KEYBINDINGS,
|
|
|
|
"Keysym %s bound to modifier 0x%x\n",
|
|
|
|
str ? str : "(null)",
|
|
|
|
(1 << ( i / modmap->max_keypermod)));
|
|
|
|
}
|
|
|
|
|
2002-04-30 23:23:46 -04:00
|
|
|
if (syms[j] == XK_Num_Lock)
|
2002-04-28 00:52:26 -04:00
|
|
|
{
|
|
|
|
/* Mod1Mask is 1 << 3 for example, i.e. the
|
|
|
|
* fourth modifier, i / keyspermod is the modifier
|
|
|
|
* index
|
|
|
|
*/
|
|
|
|
|
|
|
|
display->num_lock_mask |= (1 << ( i / modmap->max_keypermod));
|
|
|
|
}
|
|
|
|
else if (syms[j] == XK_Scroll_Lock)
|
|
|
|
{
|
|
|
|
display->scroll_lock_mask |= (1 << ( i / modmap->max_keypermod));
|
|
|
|
}
|
2002-07-13 23:16:41 -04:00
|
|
|
else if (syms[j] == XK_Super_L ||
|
|
|
|
syms[j] == XK_Super_R)
|
|
|
|
{
|
|
|
|
display->super_mask |= (1 << ( i / modmap->max_keypermod));
|
|
|
|
}
|
|
|
|
else if (syms[j] == XK_Hyper_L ||
|
|
|
|
syms[j] == XK_Hyper_R)
|
|
|
|
{
|
|
|
|
display->hyper_mask |= (1 << ( i / modmap->max_keypermod));
|
|
|
|
}
|
|
|
|
else if (syms[j] == XK_Meta_L ||
|
|
|
|
syms[j] == XK_Meta_R)
|
|
|
|
{
|
|
|
|
display->meta_mask |= (1 << ( i / modmap->max_keypermod));
|
|
|
|
}
|
2002-04-28 00:52:26 -04:00
|
|
|
|
|
|
|
++j;
|
|
|
|
}
|
|
|
|
}
|
2001-06-06 00:47:37 -04:00
|
|
|
|
|
|
|
++i;
|
|
|
|
}
|
2002-04-28 00:52:26 -04:00
|
|
|
|
2002-04-30 23:33:06 -04:00
|
|
|
display->ignored_modifier_mask = (display->num_lock_mask |
|
2002-05-10 22:38:58 -04:00
|
|
|
display->scroll_lock_mask |
|
|
|
|
LockMask);
|
2002-04-28 00:52:26 -04:00
|
|
|
|
|
|
|
meta_topic (META_DEBUG_KEYBINDINGS,
|
2002-07-13 23:16:41 -04:00
|
|
|
"Ignoring modmask 0x%x num lock 0x%x scroll lock 0x%x hyper 0x%x super 0x%x meta 0x%x\n",
|
2002-04-28 00:52:26 -04:00
|
|
|
display->ignored_modifier_mask,
|
|
|
|
display->num_lock_mask,
|
2002-07-13 23:16:41 -04:00
|
|
|
display->scroll_lock_mask,
|
|
|
|
display->hyper_mask,
|
|
|
|
display->super_mask,
|
|
|
|
display->meta_mask);
|
2002-04-28 00:52:26 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
reload_keycodes (MetaDisplay *display)
|
|
|
|
{
|
|
|
|
meta_topic (META_DEBUG_KEYBINDINGS,
|
|
|
|
"Reloading keycodes for binding tables\n");
|
|
|
|
|
|
|
|
if (display->screen_bindings)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
|
|
|
i = 0;
|
|
|
|
while (display->screen_bindings[i].keysym != None)
|
|
|
|
{
|
|
|
|
display->screen_bindings[i].keycode = XKeysymToKeycode (display->xdisplay,
|
|
|
|
display->screen_bindings[i].keysym);
|
|
|
|
|
|
|
|
++i;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (display->window_bindings)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
|
|
|
i = 0;
|
|
|
|
while (display->window_bindings[i].keysym != None)
|
|
|
|
{
|
|
|
|
display->window_bindings[i].keycode = XKeysymToKeycode (display->xdisplay,
|
|
|
|
display->window_bindings[i].keysym);
|
|
|
|
|
|
|
|
++i;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2002-07-13 23:16:41 -04:00
|
|
|
static void
|
|
|
|
reload_modifiers (MetaDisplay *display)
|
|
|
|
{
|
|
|
|
meta_topic (META_DEBUG_KEYBINDINGS,
|
|
|
|
"Reloading keycodes for binding tables\n");
|
|
|
|
|
|
|
|
if (display->screen_bindings)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
|
|
|
i = 0;
|
|
|
|
while (display->screen_bindings[i].keysym != None)
|
|
|
|
{
|
2002-10-07 19:14:40 -04:00
|
|
|
meta_display_devirtualize_modifiers (display,
|
|
|
|
display->screen_bindings[i].modifiers,
|
|
|
|
&display->screen_bindings[i].mask);
|
2002-07-13 23:16:41 -04:00
|
|
|
|
|
|
|
++i;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (display->window_bindings)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
|
|
|
i = 0;
|
|
|
|
while (display->window_bindings[i].keysym != None)
|
|
|
|
{
|
2002-10-07 19:14:40 -04:00
|
|
|
meta_display_devirtualize_modifiers (display,
|
|
|
|
display->window_bindings[i].modifiers,
|
|
|
|
&display->window_bindings[i].mask);
|
2002-07-13 23:16:41 -04:00
|
|
|
|
|
|
|
++i;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2002-04-28 00:52:26 -04:00
|
|
|
static void
|
|
|
|
rebuild_screen_binding_table (MetaDisplay *display)
|
|
|
|
{
|
|
|
|
const MetaKeyPref *prefs;
|
|
|
|
int n_bindings;
|
|
|
|
int src, dest;
|
|
|
|
|
|
|
|
meta_topic (META_DEBUG_KEYBINDINGS,
|
|
|
|
"Rebuilding screen binding table from preferences\n");
|
|
|
|
|
|
|
|
meta_prefs_get_screen_bindings (&prefs, &n_bindings);
|
|
|
|
g_free (display->screen_bindings);
|
|
|
|
display->screen_bindings = g_new0 (MetaKeyBinding, n_bindings);
|
|
|
|
|
|
|
|
src = 0;
|
|
|
|
dest = 0;
|
|
|
|
while (src < n_bindings)
|
|
|
|
{
|
2002-05-25 12:41:41 -04:00
|
|
|
if (prefs[src].keysym != None)
|
2002-04-28 00:52:26 -04:00
|
|
|
{
|
|
|
|
display->screen_bindings[dest].name = prefs[src].name;
|
|
|
|
display->screen_bindings[dest].keysym = prefs[src].keysym;
|
2002-07-13 23:16:41 -04:00
|
|
|
display->screen_bindings[dest].modifiers = prefs[src].modifiers;
|
|
|
|
display->screen_bindings[dest].mask = 0;
|
|
|
|
display->screen_bindings[dest].keycode = 0;
|
|
|
|
|
2002-04-28 00:52:26 -04:00
|
|
|
++dest;
|
|
|
|
}
|
|
|
|
|
|
|
|
++src;
|
|
|
|
}
|
|
|
|
|
|
|
|
display->n_screen_bindings = dest;
|
|
|
|
|
|
|
|
meta_topic (META_DEBUG_KEYBINDINGS,
|
|
|
|
"%d screen bindings in table\n",
|
|
|
|
display->n_screen_bindings);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
rebuild_window_binding_table (MetaDisplay *display)
|
|
|
|
{
|
|
|
|
const MetaKeyPref *prefs;
|
|
|
|
int n_bindings;
|
|
|
|
int src, dest;
|
|
|
|
|
|
|
|
meta_topic (META_DEBUG_KEYBINDINGS,
|
|
|
|
"Rebuilding window binding table from preferences\n");
|
|
|
|
|
|
|
|
meta_prefs_get_window_bindings (&prefs, &n_bindings);
|
|
|
|
g_free (display->window_bindings);
|
|
|
|
display->window_bindings = g_new0 (MetaKeyBinding, n_bindings);
|
|
|
|
|
|
|
|
src = 0;
|
|
|
|
dest = 0;
|
|
|
|
while (src < n_bindings)
|
|
|
|
{
|
2002-05-25 12:41:41 -04:00
|
|
|
if (prefs[src].keysym != None)
|
2002-04-28 00:52:26 -04:00
|
|
|
{
|
|
|
|
display->window_bindings[dest].name = prefs[src].name;
|
|
|
|
display->window_bindings[dest].keysym = prefs[src].keysym;
|
2002-07-13 23:16:41 -04:00
|
|
|
display->window_bindings[dest].modifiers = prefs[src].modifiers;
|
|
|
|
display->window_bindings[dest].mask = 0;
|
|
|
|
display->window_bindings[dest].keycode = 0;
|
|
|
|
|
2002-04-28 00:52:26 -04:00
|
|
|
++dest;
|
|
|
|
}
|
|
|
|
|
|
|
|
++src;
|
|
|
|
}
|
|
|
|
|
|
|
|
display->n_window_bindings = dest;
|
|
|
|
|
|
|
|
meta_topic (META_DEBUG_KEYBINDINGS,
|
|
|
|
"%d window bindings in table\n",
|
|
|
|
display->n_window_bindings);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
regrab_screen_bindings (MetaDisplay *display)
|
|
|
|
{
|
|
|
|
GSList *tmp;
|
|
|
|
|
2002-11-06 11:00:56 -05:00
|
|
|
meta_error_trap_push (display); /* for efficiency push outer trap */
|
|
|
|
|
2002-04-28 00:52:26 -04:00
|
|
|
tmp = display->screens;
|
|
|
|
while (tmp != NULL)
|
|
|
|
{
|
|
|
|
MetaScreen *screen = tmp->data;
|
|
|
|
|
|
|
|
meta_screen_ungrab_keys (screen);
|
|
|
|
meta_screen_grab_keys (screen);
|
|
|
|
|
|
|
|
tmp = tmp->next;
|
|
|
|
}
|
2002-11-06 11:00:56 -05:00
|
|
|
|
|
|
|
meta_error_trap_pop (display, FALSE);
|
2002-04-28 00:52:26 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
regrab_window_bindings (MetaDisplay *display)
|
|
|
|
{
|
|
|
|
GSList *windows;
|
|
|
|
GSList *tmp;
|
|
|
|
|
|
|
|
windows = meta_display_list_windows (display);
|
|
|
|
|
2002-11-06 11:00:56 -05:00
|
|
|
meta_error_trap_push (display); /* for efficiency push outer trap */
|
2002-04-28 00:52:26 -04:00
|
|
|
tmp = windows;
|
|
|
|
while (tmp != NULL)
|
|
|
|
{
|
|
|
|
MetaWindow *w = tmp->data;
|
|
|
|
|
|
|
|
meta_window_ungrab_keys (w);
|
|
|
|
meta_window_grab_keys (w);
|
|
|
|
|
|
|
|
tmp = tmp->next;
|
|
|
|
}
|
2002-11-06 11:00:56 -05:00
|
|
|
meta_error_trap_pop (display, FALSE);
|
2002-04-28 00:52:26 -04:00
|
|
|
|
|
|
|
g_slist_free (windows);
|
|
|
|
}
|
|
|
|
|
2002-07-13 23:16:41 -04:00
|
|
|
static MetaKeyBindingAction
|
|
|
|
display_get_keybinding_action (MetaDisplay *display,
|
|
|
|
unsigned int keysym,
|
|
|
|
unsigned long mask)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
|
|
|
i = display->n_screen_bindings - 1;
|
|
|
|
while (i >= 0)
|
|
|
|
{
|
|
|
|
if (display->screen_bindings[i].keysym == keysym &&
|
|
|
|
display->screen_bindings[i].mask == mask)
|
|
|
|
{
|
|
|
|
return meta_prefs_get_keybinding_action (display->screen_bindings[i].name);
|
|
|
|
}
|
|
|
|
|
|
|
|
--i;
|
|
|
|
}
|
|
|
|
|
|
|
|
return META_KEYBINDING_ACTION_NONE;
|
|
|
|
}
|
|
|
|
|
2002-04-28 00:52:26 -04:00
|
|
|
void
|
|
|
|
meta_display_process_mapping_event (MetaDisplay *display,
|
|
|
|
XEvent *event)
|
|
|
|
{
|
|
|
|
if (event->xmapping.request == MappingModifier)
|
|
|
|
{
|
|
|
|
meta_topic (META_DEBUG_KEYBINDINGS,
|
|
|
|
"Received MappingModifier event, will reload modmap and redo keybindings\n");
|
|
|
|
|
|
|
|
reload_modmap (display);
|
2002-07-13 23:16:41 -04:00
|
|
|
|
|
|
|
reload_modifiers (display);
|
2002-04-28 00:52:26 -04:00
|
|
|
|
|
|
|
regrab_screen_bindings (display);
|
|
|
|
regrab_window_bindings (display);
|
|
|
|
}
|
|
|
|
else if (event->xmapping.request == MappingKeyboard)
|
|
|
|
{
|
|
|
|
meta_topic (META_DEBUG_KEYBINDINGS,
|
|
|
|
"Received MappingKeyboard event, will reload keycodes and redo keybindings\n");
|
|
|
|
|
|
|
|
reload_keymap (display);
|
|
|
|
reload_modmap (display);
|
|
|
|
|
|
|
|
reload_keycodes (display);
|
|
|
|
|
|
|
|
regrab_screen_bindings (display);
|
|
|
|
regrab_window_bindings (display);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
bindings_changed_callback (MetaPreference pref,
|
|
|
|
void *data)
|
|
|
|
{
|
|
|
|
MetaDisplay *display;
|
|
|
|
|
|
|
|
display = data;
|
|
|
|
|
|
|
|
switch (pref)
|
|
|
|
{
|
|
|
|
case META_PREF_SCREEN_KEYBINDINGS:
|
|
|
|
rebuild_screen_binding_table (display);
|
|
|
|
reload_keycodes (display);
|
2002-07-13 23:16:41 -04:00
|
|
|
reload_modifiers (display);
|
2002-04-28 00:52:26 -04:00
|
|
|
regrab_screen_bindings (display);
|
|
|
|
break;
|
|
|
|
case META_PREF_WINDOW_KEYBINDINGS:
|
|
|
|
rebuild_window_binding_table (display);
|
|
|
|
reload_keycodes (display);
|
2002-07-13 23:16:41 -04:00
|
|
|
reload_modifiers (display);
|
2002-04-28 00:52:26 -04:00
|
|
|
regrab_window_bindings (display);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2001-06-06 00:47:37 -04:00
|
|
|
|
|
|
|
void
|
2001-06-23 01:49:35 -04:00
|
|
|
meta_display_init_keys (MetaDisplay *display)
|
|
|
|
{
|
2002-04-28 00:52:26 -04:00
|
|
|
/* Keybindings */
|
|
|
|
display->keymap = NULL;
|
|
|
|
display->keysyms_per_keycode = 0;
|
|
|
|
display->modmap = NULL;
|
|
|
|
display->min_keycode = 0;
|
|
|
|
display->max_keycode = 0;
|
|
|
|
display->ignored_modifier_mask = 0;
|
|
|
|
display->num_lock_mask = 0;
|
|
|
|
display->scroll_lock_mask = 0;
|
2002-07-13 23:16:41 -04:00
|
|
|
display->hyper_mask = 0;
|
|
|
|
display->super_mask = 0;
|
|
|
|
display->meta_mask = 0;
|
2002-04-28 00:52:26 -04:00
|
|
|
display->screen_bindings = NULL;
|
|
|
|
display->n_screen_bindings = 0;
|
|
|
|
display->window_bindings = NULL;
|
|
|
|
display->n_window_bindings = 0;
|
|
|
|
|
|
|
|
XDisplayKeycodes (display->xdisplay,
|
|
|
|
&display->min_keycode,
|
|
|
|
&display->max_keycode);
|
|
|
|
|
|
|
|
meta_topic (META_DEBUG_KEYBINDINGS,
|
|
|
|
"Display has keycode range %d to %d\n",
|
|
|
|
display->min_keycode,
|
|
|
|
display->max_keycode);
|
|
|
|
|
|
|
|
reload_keymap (display);
|
|
|
|
reload_modmap (display);
|
|
|
|
|
|
|
|
rebuild_window_binding_table (display);
|
|
|
|
rebuild_screen_binding_table (display);
|
|
|
|
|
|
|
|
reload_keycodes (display);
|
2002-07-13 23:16:41 -04:00
|
|
|
reload_modifiers (display);
|
|
|
|
|
2002-04-28 00:52:26 -04:00
|
|
|
/* Keys are actually grabbed in meta_screen_grab_keys() */
|
|
|
|
|
|
|
|
meta_prefs_add_listener (bindings_changed_callback, display);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
meta_display_shutdown_keys (MetaDisplay *display)
|
|
|
|
{
|
2002-08-06 00:11:23 -04:00
|
|
|
/* Note that display->xdisplay is invalid in this function */
|
|
|
|
|
2002-04-28 00:52:26 -04:00
|
|
|
meta_prefs_remove_listener (bindings_changed_callback, display);
|
|
|
|
|
|
|
|
if (display->keymap)
|
|
|
|
meta_XFree (display->keymap);
|
|
|
|
|
|
|
|
if (display->modmap)
|
|
|
|
XFreeModifiermap (display->modmap);
|
|
|
|
g_free (display->screen_bindings);
|
|
|
|
g_free (display->window_bindings);
|
|
|
|
}
|
|
|
|
|
|
|
|
static const char*
|
|
|
|
keysym_name (int keysym)
|
|
|
|
{
|
|
|
|
const char *name;
|
|
|
|
|
|
|
|
name = XKeysymToString (keysym);
|
|
|
|
if (name == NULL)
|
|
|
|
name = "(unknown)";
|
|
|
|
|
|
|
|
return name;
|
2001-06-23 01:49:35 -04:00
|
|
|
}
|
|
|
|
|
2001-10-04 22:58:48 -04:00
|
|
|
/* Grab/ungrab, ignoring all annoying modifiers like NumLock etc. */
|
|
|
|
static void
|
|
|
|
meta_change_keygrab (MetaDisplay *display,
|
|
|
|
Window xwindow,
|
|
|
|
gboolean grab,
|
|
|
|
int keysym,
|
|
|
|
int keycode,
|
|
|
|
int modmask)
|
|
|
|
{
|
|
|
|
int ignored_mask;
|
|
|
|
|
|
|
|
/* Grab keycode/modmask, together with
|
2002-04-28 00:52:26 -04:00
|
|
|
* all combinations of ignored modifiers.
|
2001-10-04 22:58:48 -04:00
|
|
|
* X provides no better way to do this.
|
|
|
|
*/
|
2002-04-28 00:52:26 -04:00
|
|
|
|
|
|
|
meta_topic (META_DEBUG_KEYBINDINGS,
|
2002-06-08 23:44:16 -04:00
|
|
|
"%s keybinding %s mask 0x%x on 0x%lx\n",
|
2002-04-28 00:52:26 -04:00
|
|
|
grab ? "Grabbing" : "Ungrabbing",
|
|
|
|
keysym_name (keysym),
|
2002-06-08 23:44:16 -04:00
|
|
|
modmask, xwindow);
|
2002-10-21 17:44:35 -04:00
|
|
|
|
|
|
|
/* efficiency, avoid so many XSync() */
|
|
|
|
meta_error_trap_push (display);
|
2001-10-04 22:58:48 -04:00
|
|
|
|
|
|
|
ignored_mask = 0;
|
2002-04-28 00:52:26 -04:00
|
|
|
while (ignored_mask < (int) display->ignored_modifier_mask)
|
2001-10-04 22:58:48 -04:00
|
|
|
{
|
2002-04-28 00:52:26 -04:00
|
|
|
if (ignored_mask & ~(display->ignored_modifier_mask))
|
2001-10-04 22:58:48 -04:00
|
|
|
{
|
2002-04-28 00:52:26 -04:00
|
|
|
/* Not a combination of ignored modifiers
|
2001-10-04 22:58:48 -04:00
|
|
|
* (it contains some non-ignored modifiers)
|
|
|
|
*/
|
|
|
|
++ignored_mask;
|
|
|
|
continue;
|
|
|
|
}
|
2002-10-21 17:44:35 -04:00
|
|
|
|
|
|
|
if (meta_is_debugging ())
|
|
|
|
meta_error_trap_push_with_return (display);
|
2001-10-04 22:58:48 -04:00
|
|
|
if (grab)
|
|
|
|
XGrabKey (display->xdisplay, keycode,
|
|
|
|
modmask | ignored_mask,
|
|
|
|
xwindow,
|
|
|
|
True,
|
2002-02-08 01:01:58 -05:00
|
|
|
GrabModeAsync, GrabModeSync);
|
2001-10-04 22:58:48 -04:00
|
|
|
else
|
|
|
|
XUngrabKey (display->xdisplay, keycode,
|
|
|
|
modmask | ignored_mask,
|
|
|
|
xwindow);
|
2002-10-21 17:44:35 -04:00
|
|
|
|
|
|
|
if (meta_is_debugging ())
|
|
|
|
{
|
|
|
|
int result;
|
|
|
|
|
|
|
|
result = meta_error_trap_pop_with_return (display, FALSE);
|
|
|
|
|
|
|
|
if (grab && result != Success)
|
|
|
|
{
|
|
|
|
if (result == BadAccess)
|
|
|
|
meta_warning (_("Some other program is already using the key %s with modifiers %x as a binding\n"), keysym_name (keysym), modmask | ignored_mask);
|
|
|
|
else
|
|
|
|
meta_topic (META_DEBUG_KEYBINDINGS,
|
|
|
|
"Failed to grab key %s with modifiers %x\n",
|
|
|
|
keysym_name (keysym), modmask | ignored_mask);
|
|
|
|
}
|
2001-10-04 22:58:48 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
++ignored_mask;
|
|
|
|
}
|
2002-10-21 17:44:35 -04:00
|
|
|
|
|
|
|
meta_error_trap_pop (display, FALSE);
|
2001-10-04 22:58:48 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
meta_grab_key (MetaDisplay *display,
|
|
|
|
Window xwindow,
|
|
|
|
int keysym,
|
|
|
|
int keycode,
|
|
|
|
int modmask)
|
|
|
|
{
|
|
|
|
meta_change_keygrab (display, xwindow, TRUE, keysym, keycode, modmask);
|
|
|
|
}
|
|
|
|
|
2001-06-23 01:49:35 -04:00
|
|
|
static void
|
|
|
|
grab_keys (MetaKeyBinding *bindings,
|
2002-04-28 00:52:26 -04:00
|
|
|
int n_bindings,
|
2001-06-23 01:49:35 -04:00
|
|
|
MetaDisplay *display,
|
|
|
|
Window xwindow)
|
2001-06-06 00:47:37 -04:00
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
2002-04-28 00:52:26 -04:00
|
|
|
g_assert (n_bindings == 0 || bindings != NULL);
|
2002-11-06 11:00:56 -05:00
|
|
|
|
|
|
|
meta_error_trap_push (display);
|
2002-04-28 00:52:26 -04:00
|
|
|
|
2001-06-06 00:47:37 -04:00
|
|
|
i = 0;
|
2002-04-28 00:52:26 -04:00
|
|
|
while (i < n_bindings)
|
2001-06-06 00:47:37 -04:00
|
|
|
{
|
|
|
|
if (bindings[i].keycode != 0)
|
|
|
|
{
|
2001-10-04 22:58:48 -04:00
|
|
|
meta_grab_key (display, xwindow,
|
|
|
|
bindings[i].keysym,
|
|
|
|
bindings[i].keycode,
|
|
|
|
bindings[i].mask);
|
2001-06-06 00:47:37 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
++i;
|
|
|
|
}
|
2002-11-06 11:00:56 -05:00
|
|
|
|
|
|
|
meta_error_trap_pop (display, FALSE);
|
2001-06-06 00:47:37 -04:00
|
|
|
}
|
|
|
|
|
2001-06-23 01:49:35 -04:00
|
|
|
static void
|
2002-04-28 00:52:26 -04:00
|
|
|
ungrab_all_keys (MetaDisplay *display,
|
|
|
|
Window xwindow)
|
2001-06-06 00:47:37 -04:00
|
|
|
{
|
2002-11-06 11:00:56 -05:00
|
|
|
if (meta_is_debugging ())
|
|
|
|
meta_error_trap_push_with_return (display);
|
|
|
|
else
|
|
|
|
meta_error_trap_push (display);
|
2001-06-06 00:47:37 -04:00
|
|
|
|
2002-04-28 00:52:26 -04:00
|
|
|
XUngrabKey (display->xdisplay, AnyKey, AnyModifier,
|
|
|
|
xwindow);
|
2002-11-06 11:00:56 -05:00
|
|
|
|
|
|
|
if (meta_is_debugging ())
|
|
|
|
{
|
|
|
|
int result;
|
2001-06-06 00:47:37 -04:00
|
|
|
|
2002-11-06 11:00:56 -05:00
|
|
|
result = meta_error_trap_pop_with_return (display, FALSE);
|
|
|
|
|
|
|
|
if (result != Success)
|
|
|
|
meta_topic (META_DEBUG_KEYBINDINGS,
|
|
|
|
"Ungrabbing all keys on 0x%lx failed\n", xwindow);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
meta_error_trap_pop (display, FALSE);
|
2001-06-06 00:47:37 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2002-04-28 00:52:26 -04:00
|
|
|
meta_screen_grab_keys (MetaScreen *screen)
|
2001-06-23 01:49:35 -04:00
|
|
|
{
|
2002-06-30 23:20:29 -04:00
|
|
|
if (screen->all_keys_grabbed)
|
|
|
|
return;
|
|
|
|
|
2002-04-28 00:52:26 -04:00
|
|
|
if (screen->keys_grabbed)
|
|
|
|
return;
|
|
|
|
|
|
|
|
grab_keys (screen->display->screen_bindings,
|
|
|
|
screen->display->n_screen_bindings,
|
|
|
|
screen->display, screen->xroot);
|
|
|
|
|
|
|
|
screen->keys_grabbed = TRUE;
|
2001-06-23 01:49:35 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
meta_screen_ungrab_keys (MetaScreen *screen)
|
|
|
|
{
|
2002-04-28 00:52:26 -04:00
|
|
|
if (screen->keys_grabbed)
|
|
|
|
{
|
|
|
|
ungrab_all_keys (screen->display, screen->xroot);
|
|
|
|
screen->keys_grabbed = FALSE;
|
|
|
|
}
|
2001-06-23 01:49:35 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
meta_window_grab_keys (MetaWindow *window)
|
|
|
|
{
|
2001-07-11 02:22:00 -04:00
|
|
|
if (window->all_keys_grabbed)
|
|
|
|
return;
|
|
|
|
|
2001-06-23 01:49:35 -04:00
|
|
|
if (window->keys_grabbed)
|
|
|
|
{
|
|
|
|
if (window->frame && !window->grab_on_frame)
|
2002-04-28 00:52:26 -04:00
|
|
|
ungrab_all_keys (window->display, window->xwindow);
|
2001-06-23 01:49:35 -04:00
|
|
|
else if (window->frame == NULL &&
|
|
|
|
window->grab_on_frame)
|
|
|
|
; /* continue to regrab on client window */
|
|
|
|
else
|
|
|
|
return; /* already all good */
|
|
|
|
}
|
2001-06-23 02:54:28 -04:00
|
|
|
|
2002-04-28 00:52:26 -04:00
|
|
|
grab_keys (window->display->window_bindings,
|
|
|
|
window->display->n_window_bindings,
|
|
|
|
window->display,
|
2001-06-23 01:49:35 -04:00
|
|
|
window->frame ? window->frame->xwindow : window->xwindow);
|
|
|
|
|
|
|
|
window->keys_grabbed = TRUE;
|
|
|
|
window->grab_on_frame = window->frame != NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
meta_window_ungrab_keys (MetaWindow *window)
|
|
|
|
{
|
|
|
|
if (window->keys_grabbed)
|
|
|
|
{
|
|
|
|
if (window->grab_on_frame &&
|
|
|
|
window->frame != NULL)
|
2002-04-28 00:52:26 -04:00
|
|
|
ungrab_all_keys (window->display,
|
|
|
|
window->frame->xwindow);
|
2001-06-23 01:49:35 -04:00
|
|
|
else if (!window->grab_on_frame)
|
2002-04-28 00:52:26 -04:00
|
|
|
ungrab_all_keys (window->display,
|
|
|
|
window->xwindow);
|
2002-06-08 20:09:01 -04:00
|
|
|
|
|
|
|
window->keys_grabbed = FALSE;
|
2001-06-23 01:49:35 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2002-06-27 01:08:32 -04:00
|
|
|
static gboolean
|
2002-07-02 01:03:28 -04:00
|
|
|
grab_keyboard (MetaDisplay *display,
|
|
|
|
Window xwindow)
|
2002-06-27 01:08:32 -04:00
|
|
|
{
|
|
|
|
int result;
|
|
|
|
|
2002-07-02 01:03:28 -04:00
|
|
|
/* Grab the keyboard, so we get key releases and all key
|
2002-06-27 01:08:32 -04:00
|
|
|
* presses
|
|
|
|
*/
|
2002-10-21 17:44:35 -04:00
|
|
|
meta_error_trap_push_with_return (display);
|
2002-06-27 01:08:32 -04:00
|
|
|
|
2002-10-21 17:44:35 -04:00
|
|
|
if (XGrabKeyboard (display->xdisplay,
|
|
|
|
xwindow, True,
|
|
|
|
GrabModeAsync, GrabModeAsync,
|
|
|
|
meta_display_get_current_time (display)) != GrabSuccess)
|
2002-06-27 01:08:32 -04:00
|
|
|
{
|
2002-10-21 17:44:35 -04:00
|
|
|
meta_error_trap_pop_with_return (display, TRUE);
|
2002-06-27 01:08:32 -04:00
|
|
|
meta_topic (META_DEBUG_KEYBINDINGS,
|
2002-10-21 17:44:35 -04:00
|
|
|
"XGrabKeyboard() returned failure\n");
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
result = meta_error_trap_pop_with_return (display, TRUE);
|
|
|
|
if (result != Success)
|
|
|
|
{
|
|
|
|
meta_topic (META_DEBUG_KEYBINDINGS,
|
|
|
|
"XGrabKeyboard() resulted in an error\n");
|
|
|
|
return FALSE;
|
|
|
|
}
|
2002-06-27 01:08:32 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
meta_topic (META_DEBUG_KEYBINDINGS, "Grabbed all keys\n");
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2002-07-02 01:03:28 -04:00
|
|
|
ungrab_keyboard (MetaDisplay *display)
|
2002-06-27 01:08:32 -04:00
|
|
|
{
|
|
|
|
Time timestamp;
|
|
|
|
|
|
|
|
timestamp = meta_display_get_current_time (display);
|
|
|
|
|
|
|
|
meta_error_trap_push (display);
|
|
|
|
|
|
|
|
meta_topic (META_DEBUG_KEYBINDINGS,
|
|
|
|
"Ungrabbing keyboard with timestamp %lu\n",
|
|
|
|
timestamp);
|
|
|
|
XUngrabKeyboard (display->xdisplay, timestamp);
|
2002-10-21 17:44:35 -04:00
|
|
|
meta_error_trap_pop (display, FALSE);
|
2002-06-27 01:08:32 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
gboolean
|
|
|
|
meta_screen_grab_all_keys (MetaScreen *screen)
|
|
|
|
{
|
|
|
|
gboolean retval;
|
|
|
|
|
|
|
|
if (screen->all_keys_grabbed)
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
if (screen->keys_grabbed)
|
|
|
|
meta_screen_ungrab_keys (screen);
|
|
|
|
|
|
|
|
meta_topic (META_DEBUG_KEYBINDINGS,
|
|
|
|
"Grabbing all keys on RootWindow\n");
|
2002-07-02 01:03:28 -04:00
|
|
|
retval = grab_keyboard (screen->display, screen->xroot);
|
2002-06-27 01:08:32 -04:00
|
|
|
if (retval)
|
2002-06-30 23:20:29 -04:00
|
|
|
screen->all_keys_grabbed = TRUE;
|
|
|
|
else
|
|
|
|
meta_screen_grab_keys (screen);
|
2002-06-27 01:08:32 -04:00
|
|
|
|
|
|
|
return retval;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
meta_screen_ungrab_all_keys (MetaScreen *screen)
|
|
|
|
{
|
|
|
|
if (screen->all_keys_grabbed)
|
|
|
|
{
|
2002-07-02 01:03:28 -04:00
|
|
|
ungrab_keyboard (screen->display);
|
2002-06-27 01:08:32 -04:00
|
|
|
|
|
|
|
screen->all_keys_grabbed = FALSE;
|
|
|
|
screen->keys_grabbed = FALSE;
|
|
|
|
|
|
|
|
/* Re-establish our standard bindings */
|
|
|
|
meta_screen_grab_keys (screen);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2001-07-11 02:22:00 -04:00
|
|
|
gboolean
|
|
|
|
meta_window_grab_all_keys (MetaWindow *window)
|
|
|
|
{
|
|
|
|
Window grabwindow;
|
2002-06-27 01:08:32 -04:00
|
|
|
gboolean retval;
|
2001-07-11 02:22:00 -04:00
|
|
|
|
|
|
|
if (window->all_keys_grabbed)
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
if (window->keys_grabbed)
|
|
|
|
meta_window_ungrab_keys (window);
|
|
|
|
|
|
|
|
/* Make sure the window is focused, otherwise the grab
|
|
|
|
* won't do a lot of good.
|
|
|
|
*/
|
2002-01-03 18:28:19 -05:00
|
|
|
meta_topic (META_DEBUG_FOCUS,
|
|
|
|
"Focusing %s because we're grabbing all its keys\n",
|
|
|
|
window->desc);
|
|
|
|
meta_window_focus (window,
|
|
|
|
meta_display_get_current_time (window->display));
|
2001-07-11 02:22:00 -04:00
|
|
|
|
|
|
|
grabwindow = window->frame ? window->frame->xwindow : window->xwindow;
|
2002-06-27 01:08:32 -04:00
|
|
|
|
|
|
|
meta_topic (META_DEBUG_KEYBINDINGS,
|
|
|
|
"Grabbing all keys on window %s\n", window->desc);
|
2002-07-02 01:03:28 -04:00
|
|
|
retval = grab_keyboard (window->display, grabwindow);
|
2002-06-27 01:08:32 -04:00
|
|
|
if (retval)
|
2001-07-11 02:22:00 -04:00
|
|
|
{
|
2002-06-27 01:08:32 -04:00
|
|
|
window->keys_grabbed = FALSE;
|
|
|
|
window->all_keys_grabbed = TRUE;
|
|
|
|
window->grab_on_frame = window->frame != NULL;
|
2001-07-11 02:22:00 -04:00
|
|
|
}
|
2002-01-03 18:28:19 -05:00
|
|
|
|
2002-06-27 01:08:32 -04:00
|
|
|
return retval;
|
2001-07-11 02:22:00 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2002-07-02 01:03:28 -04:00
|
|
|
meta_window_ungrab_all_keys (MetaWindow *window)
|
2001-07-11 02:22:00 -04:00
|
|
|
{
|
|
|
|
if (window->all_keys_grabbed)
|
|
|
|
{
|
2002-07-02 01:03:28 -04:00
|
|
|
ungrab_keyboard (window->display);
|
2002-01-03 18:28:19 -05:00
|
|
|
|
2001-07-11 02:22:00 -04:00
|
|
|
window->grab_on_frame = FALSE;
|
|
|
|
window->all_keys_grabbed = FALSE;
|
|
|
|
window->keys_grabbed = FALSE;
|
|
|
|
|
|
|
|
/* Re-establish our standard bindings */
|
|
|
|
meta_window_grab_keys (window);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
is_modifier (MetaDisplay *display,
|
|
|
|
unsigned int keycode)
|
|
|
|
{
|
2001-08-19 14:09:10 -04:00
|
|
|
int i;
|
|
|
|
int map_size;
|
2002-04-28 00:52:26 -04:00
|
|
|
gboolean retval = FALSE;
|
|
|
|
|
|
|
|
g_assert (display->modmap);
|
2001-08-19 14:09:10 -04:00
|
|
|
|
2002-04-28 00:52:26 -04:00
|
|
|
map_size = 8 * display->modmap->max_keypermod;
|
2001-08-19 14:09:10 -04:00
|
|
|
i = 0;
|
|
|
|
while (i < map_size)
|
|
|
|
{
|
2002-04-28 00:52:26 -04:00
|
|
|
if (keycode == display->modmap->modifiermap[i])
|
2001-08-19 14:09:10 -04:00
|
|
|
{
|
|
|
|
retval = TRUE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
++i;
|
|
|
|
}
|
|
|
|
|
|
|
|
return retval;
|
|
|
|
}
|
|
|
|
|
2002-04-28 00:52:26 -04:00
|
|
|
/* Indexes:
|
|
|
|
* shift = 0
|
|
|
|
* lock = 1
|
|
|
|
* control = 2
|
|
|
|
* mod1 = 3
|
|
|
|
* mod2 = 4
|
|
|
|
* mod3 = 5
|
|
|
|
* mod4 = 6
|
|
|
|
* mod5 = 7
|
|
|
|
*/
|
|
|
|
|
2001-08-19 14:09:10 -04:00
|
|
|
static gboolean
|
2002-04-28 00:52:26 -04:00
|
|
|
is_specific_modifier (MetaDisplay *display,
|
|
|
|
unsigned int keycode,
|
|
|
|
unsigned int mask)
|
2001-08-19 14:09:10 -04:00
|
|
|
{
|
|
|
|
int i;
|
|
|
|
int end;
|
|
|
|
gboolean retval = FALSE;
|
2002-04-28 00:52:26 -04:00
|
|
|
int mod_index;
|
2001-08-19 14:09:10 -04:00
|
|
|
|
2002-04-28 00:52:26 -04:00
|
|
|
g_assert (display->modmap);
|
|
|
|
|
|
|
|
meta_topic (META_DEBUG_KEYBINDINGS,
|
|
|
|
"Checking whether code 0x%x is bound to modifier 0x%x\n",
|
|
|
|
keycode, mask);
|
2001-08-19 14:09:10 -04:00
|
|
|
|
2002-04-28 00:52:26 -04:00
|
|
|
mod_index = 0;
|
|
|
|
mask = mask >> 1;
|
|
|
|
while (mask != 0)
|
|
|
|
{
|
|
|
|
mod_index += 1;
|
|
|
|
mask = mask >> 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
meta_topic (META_DEBUG_KEYBINDINGS,
|
|
|
|
"Modifier has index %d\n", mod_index);
|
2001-08-19 14:09:10 -04:00
|
|
|
|
2002-04-28 00:52:26 -04:00
|
|
|
end = (mod_index + 1) * display->modmap->max_keypermod;
|
|
|
|
i = mod_index * display->modmap->max_keypermod;
|
2001-08-19 14:09:10 -04:00
|
|
|
while (i < end)
|
|
|
|
{
|
2002-04-28 00:52:26 -04:00
|
|
|
if (keycode == display->modmap->modifiermap[i])
|
2001-08-19 14:09:10 -04:00
|
|
|
{
|
|
|
|
retval = TRUE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
++i;
|
|
|
|
}
|
|
|
|
|
|
|
|
return retval;
|
2001-07-11 02:22:00 -04:00
|
|
|
}
|
|
|
|
|
2002-04-28 00:52:26 -04:00
|
|
|
static gboolean
|
|
|
|
keycode_is_primary_modifier (MetaDisplay *display,
|
|
|
|
unsigned int keycode,
|
|
|
|
unsigned int entire_binding_mask)
|
|
|
|
{
|
|
|
|
/* The idea here is to see if the "main" modifier
|
|
|
|
* for Alt+Tab has been pressed/released. So if the binding
|
|
|
|
* is Alt+Shift+Tab then releasing Alt is the thing that
|
|
|
|
* ends the operation. It's pretty random how we order
|
|
|
|
* these.
|
|
|
|
*/
|
|
|
|
unsigned int masks[] = { Mod5Mask, Mod4Mask, Mod3Mask,
|
|
|
|
Mod2Mask, Mod1Mask, ControlMask,
|
|
|
|
ShiftMask, LockMask };
|
|
|
|
|
|
|
|
int i;
|
|
|
|
|
|
|
|
meta_topic (META_DEBUG_KEYBINDINGS,
|
|
|
|
"Checking whether code 0x%x is the primary modifier of mask 0x%x\n",
|
|
|
|
keycode, entire_binding_mask);
|
|
|
|
|
|
|
|
i = 0;
|
|
|
|
while (i < (int) G_N_ELEMENTS (masks))
|
|
|
|
{
|
|
|
|
if (entire_binding_mask & masks[i])
|
|
|
|
return is_specific_modifier (display, keycode, masks[i]);
|
|
|
|
++i;
|
|
|
|
}
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static const MetaKeyHandler*
|
|
|
|
find_handler (const MetaKeyHandler *handlers,
|
|
|
|
const char *name)
|
|
|
|
{
|
|
|
|
const MetaKeyHandler *iter;
|
|
|
|
|
|
|
|
iter = handlers;
|
|
|
|
while (iter->name)
|
|
|
|
{
|
|
|
|
if (strcmp (iter->name,
|
|
|
|
name) == 0)
|
|
|
|
return iter;
|
|
|
|
|
|
|
|
++iter;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2001-06-23 01:49:35 -04:00
|
|
|
static void
|
2002-04-28 00:52:26 -04:00
|
|
|
process_event (MetaKeyBinding *bindings,
|
|
|
|
int n_bindings,
|
|
|
|
const MetaKeyHandler *handlers,
|
|
|
|
MetaDisplay *display,
|
2002-10-16 16:12:24 -04:00
|
|
|
MetaScreen *screen,
|
2002-04-28 00:52:26 -04:00
|
|
|
MetaWindow *window,
|
|
|
|
XEvent *event,
|
|
|
|
KeySym keysym)
|
2001-06-06 00:47:37 -04:00
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
2002-06-15 23:03:08 -04:00
|
|
|
/* we used to have release-based bindings but no longer. */
|
|
|
|
if (event->type == KeyRelease)
|
|
|
|
return;
|
|
|
|
|
2001-06-06 00:47:37 -04:00
|
|
|
i = 0;
|
2002-04-28 00:52:26 -04:00
|
|
|
while (i < n_bindings)
|
2001-06-06 00:47:37 -04:00
|
|
|
{
|
|
|
|
if (bindings[i].keysym == keysym &&
|
2002-04-28 00:52:26 -04:00
|
|
|
((event->xkey.state & ~(display->ignored_modifier_mask)) ==
|
2001-06-23 22:22:10 -04:00
|
|
|
bindings[i].mask) &&
|
2002-04-28 00:52:26 -04:00
|
|
|
event->type == KeyPress)
|
2001-06-06 00:47:37 -04:00
|
|
|
{
|
2002-04-28 00:52:26 -04:00
|
|
|
const MetaKeyHandler *handler;
|
|
|
|
|
|
|
|
if (bindings[i].handler)
|
|
|
|
handler = bindings[i].handler;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
handler = find_handler (handlers, bindings[i].name);
|
|
|
|
bindings[i].handler = handler; /* cache */
|
|
|
|
}
|
|
|
|
|
|
|
|
if (handler == NULL)
|
|
|
|
meta_bug ("Binding %s has no handler\n", bindings[i].name);
|
2002-06-15 23:03:08 -04:00
|
|
|
else
|
|
|
|
meta_topic (META_DEBUG_KEYBINDINGS,
|
|
|
|
"Running handler for %s\n",
|
|
|
|
bindings[i].name);
|
2002-04-28 00:52:26 -04:00
|
|
|
|
2002-10-16 16:12:24 -04:00
|
|
|
(* handler->func) (display, screen, window, event,
|
2002-04-28 00:52:26 -04:00
|
|
|
&bindings[i]);
|
2002-06-15 23:03:08 -04:00
|
|
|
return;
|
2001-06-06 00:47:37 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
++i;
|
|
|
|
}
|
2002-06-15 23:03:08 -04:00
|
|
|
|
|
|
|
meta_topic (META_DEBUG_KEYBINDINGS,
|
|
|
|
"No handler found for this event in this binding table\n");
|
2001-06-06 00:47:37 -04:00
|
|
|
}
|
2002-06-27 01:08:32 -04:00
|
|
|
|
2001-06-23 01:49:35 -04:00
|
|
|
void
|
2001-06-23 22:22:10 -04:00
|
|
|
meta_display_process_key_event (MetaDisplay *display,
|
2001-06-23 01:49:35 -04:00
|
|
|
MetaWindow *window,
|
|
|
|
XEvent *event)
|
|
|
|
{
|
2001-07-11 02:22:00 -04:00
|
|
|
KeySym keysym;
|
|
|
|
gboolean handled;
|
2002-06-27 01:08:32 -04:00
|
|
|
gboolean all_keys_grabbed;
|
2002-06-15 23:03:08 -04:00
|
|
|
const char *str;
|
2002-06-27 01:08:32 -04:00
|
|
|
MetaScreen *screen;
|
2001-07-11 02:22:00 -04:00
|
|
|
|
2002-02-08 01:01:58 -05:00
|
|
|
XAllowEvents (display->xdisplay,
|
|
|
|
all_bindings_disabled ? ReplayKeyboard : AsyncKeyboard,
|
|
|
|
event->xkey.time);
|
|
|
|
if (all_bindings_disabled)
|
|
|
|
return;
|
2002-06-27 01:08:32 -04:00
|
|
|
|
2002-10-16 16:12:24 -04:00
|
|
|
/* if key event was on root window, we have a shortcut */
|
|
|
|
screen = meta_display_screen_for_root (display, event->xkey.window);
|
|
|
|
|
|
|
|
/* else round-trip to server */
|
|
|
|
if (screen == NULL)
|
|
|
|
screen = meta_display_screen_for_xwindow (display,
|
|
|
|
event->xany.window);
|
2002-06-27 01:08:32 -04:00
|
|
|
|
2002-07-23 15:12:02 -04:00
|
|
|
if (screen == NULL)
|
|
|
|
return; /* event window is destroyed */
|
2002-10-16 16:12:24 -04:00
|
|
|
|
2002-08-10 11:55:18 -04:00
|
|
|
/* ignore key events on popup menus and such. */
|
|
|
|
if (window == NULL &&
|
|
|
|
meta_ui_window_is_widget (screen->ui, event->xany.window))
|
|
|
|
return;
|
2002-07-23 15:12:02 -04:00
|
|
|
|
2002-08-10 11:55:18 -04:00
|
|
|
/* window may be NULL */
|
2001-07-11 02:22:00 -04:00
|
|
|
|
|
|
|
keysym = XKeycodeToKeysym (display->xdisplay, event->xkey.keycode, 0);
|
2002-06-15 23:03:08 -04:00
|
|
|
|
|
|
|
str = XKeysymToString (keysym);
|
2001-07-11 02:22:00 -04:00
|
|
|
|
2002-04-28 00:52:26 -04:00
|
|
|
meta_topic (META_DEBUG_KEYBINDINGS,
|
|
|
|
"Processing key %s event, keysym: %s state: 0x%x window: %s\n",
|
|
|
|
event->type == KeyPress ? "press" : "release",
|
2002-06-15 23:03:08 -04:00
|
|
|
str ? str : "(null)", event->xkey.state,
|
2002-04-28 00:52:26 -04:00
|
|
|
window ? window->desc : "(no window)");
|
2001-07-11 02:22:00 -04:00
|
|
|
|
2002-06-27 01:08:32 -04:00
|
|
|
all_keys_grabbed = window ? window->all_keys_grabbed : screen->all_keys_grabbed;
|
|
|
|
if (!all_keys_grabbed)
|
2001-07-11 02:22:00 -04:00
|
|
|
{
|
|
|
|
/* Do the normal keybindings */
|
2002-04-28 00:52:26 -04:00
|
|
|
process_event (display->screen_bindings,
|
|
|
|
display->n_screen_bindings,
|
|
|
|
screen_handlers,
|
2002-10-16 16:12:24 -04:00
|
|
|
display, screen, NULL, event, keysym);
|
2001-07-25 23:58:24 -04:00
|
|
|
|
|
|
|
if (window)
|
2002-04-28 00:52:26 -04:00
|
|
|
process_event (display->window_bindings,
|
|
|
|
display->n_window_bindings,
|
|
|
|
window_handlers,
|
2002-10-16 16:12:24 -04:00
|
|
|
display, screen, window, event, keysym);
|
2001-08-19 14:09:10 -04:00
|
|
|
|
2001-07-11 02:22:00 -04:00
|
|
|
return;
|
|
|
|
}
|
2002-06-08 23:44:16 -04:00
|
|
|
|
2001-08-19 14:09:10 -04:00
|
|
|
if (display->grab_op == META_GRAB_OP_NONE)
|
|
|
|
return;
|
2001-07-11 02:22:00 -04:00
|
|
|
|
|
|
|
/* If we get here we have a global grab, because
|
|
|
|
* we're in some special keyboard mode such as window move
|
|
|
|
* mode.
|
|
|
|
*/
|
|
|
|
|
|
|
|
handled = FALSE;
|
2001-07-25 23:14:45 -04:00
|
|
|
|
2002-06-27 01:08:32 -04:00
|
|
|
if (window ? (window == display->grab_window) :
|
|
|
|
(screen == display->grab_screen))
|
2001-07-11 02:22:00 -04:00
|
|
|
{
|
2001-08-19 14:09:10 -04:00
|
|
|
switch (display->grab_op)
|
|
|
|
{
|
|
|
|
case META_GRAB_OP_KEYBOARD_MOVING:
|
2002-04-28 00:52:26 -04:00
|
|
|
meta_topic (META_DEBUG_KEYBINDINGS,
|
|
|
|
"Processing event for keyboard move\n");
|
2002-06-27 01:08:32 -04:00
|
|
|
g_assert (window != NULL);
|
2002-10-16 16:12:24 -04:00
|
|
|
handled = process_keyboard_move_grab (display, screen,
|
|
|
|
window, event, keysym);
|
2001-08-19 14:09:10 -04:00
|
|
|
break;
|
2002-06-19 00:12:49 -04:00
|
|
|
|
|
|
|
case META_GRAB_OP_KEYBOARD_RESIZING_UNKNOWN:
|
|
|
|
case META_GRAB_OP_KEYBOARD_RESIZING_S:
|
|
|
|
case META_GRAB_OP_KEYBOARD_RESIZING_N:
|
|
|
|
case META_GRAB_OP_KEYBOARD_RESIZING_W:
|
|
|
|
case META_GRAB_OP_KEYBOARD_RESIZING_E:
|
|
|
|
case META_GRAB_OP_KEYBOARD_RESIZING_SE:
|
|
|
|
case META_GRAB_OP_KEYBOARD_RESIZING_NE:
|
|
|
|
case META_GRAB_OP_KEYBOARD_RESIZING_SW:
|
|
|
|
case META_GRAB_OP_KEYBOARD_RESIZING_NW:
|
|
|
|
meta_topic (META_DEBUG_KEYBINDINGS,
|
|
|
|
"Processing event for keyboard resize\n");
|
2002-06-27 01:08:32 -04:00
|
|
|
g_assert (window != NULL);
|
2002-10-16 16:12:24 -04:00
|
|
|
handled = process_keyboard_resize_grab (display, screen,
|
|
|
|
window, event, keysym);
|
2002-06-19 00:12:49 -04:00
|
|
|
break;
|
|
|
|
|
2002-04-05 10:52:49 -05:00
|
|
|
case META_GRAB_OP_KEYBOARD_TABBING_NORMAL:
|
|
|
|
case META_GRAB_OP_KEYBOARD_TABBING_DOCK:
|
2002-07-06 12:50:48 -04:00
|
|
|
case META_GRAB_OP_KEYBOARD_ESCAPING_NORMAL:
|
|
|
|
case META_GRAB_OP_KEYBOARD_ESCAPING_DOCK:
|
2002-04-28 00:52:26 -04:00
|
|
|
meta_topic (META_DEBUG_KEYBINDINGS,
|
2002-07-06 12:50:48 -04:00
|
|
|
"Processing event for keyboard tabbing/cycling\n");
|
2002-10-16 16:12:24 -04:00
|
|
|
handled = process_tab_grab (display, screen, event, keysym);
|
2001-08-19 14:09:10 -04:00
|
|
|
break;
|
2002-07-06 12:50:48 -04:00
|
|
|
|
2002-06-09 00:04:19 -04:00
|
|
|
case META_GRAB_OP_KEYBOARD_WORKSPACE_SWITCHING:
|
2002-06-08 23:44:16 -04:00
|
|
|
meta_topic (META_DEBUG_KEYBINDINGS,
|
2002-06-09 00:04:19 -04:00
|
|
|
"Processing event for keyboard workspace switching\n");
|
2002-10-16 16:12:24 -04:00
|
|
|
handled = process_workspace_switch_grab (display, screen, event, keysym);
|
2002-06-08 23:44:16 -04:00
|
|
|
break;
|
|
|
|
|
2001-08-19 14:09:10 -04:00
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* end grab if a key that isn't used gets pressed */
|
|
|
|
if (!handled)
|
|
|
|
{
|
2002-04-28 00:52:26 -04:00
|
|
|
meta_topic (META_DEBUG_KEYBINDINGS,
|
|
|
|
"Ending grab op %d on key event sym %s\n",
|
|
|
|
display->grab_op, XKeysymToString (keysym));
|
2001-08-19 14:09:10 -04:00
|
|
|
meta_display_end_grab_op (display, event->xkey.time);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
process_keyboard_move_grab (MetaDisplay *display,
|
2002-10-16 16:12:24 -04:00
|
|
|
MetaScreen *screen,
|
2001-08-19 14:09:10 -04:00
|
|
|
MetaWindow *window,
|
|
|
|
XEvent *event,
|
|
|
|
KeySym keysym)
|
|
|
|
{
|
|
|
|
gboolean handled;
|
|
|
|
int x, y;
|
|
|
|
int incr;
|
|
|
|
gboolean smart_snap;
|
|
|
|
int edge;
|
|
|
|
|
|
|
|
handled = FALSE;
|
2001-07-11 02:22:00 -04:00
|
|
|
|
2001-08-19 14:09:10 -04:00
|
|
|
/* don't care about releases, but eat them, don't end grab */
|
|
|
|
if (event->type == KeyRelease)
|
|
|
|
return TRUE;
|
2001-07-11 02:22:00 -04:00
|
|
|
|
2001-08-19 14:09:10 -04:00
|
|
|
/* don't end grab on modifier key presses */
|
|
|
|
if (is_modifier (display, event->xkey.keycode))
|
|
|
|
return TRUE;
|
|
|
|
|
|
|
|
meta_window_get_position (window, &x, &y);
|
|
|
|
|
|
|
|
smart_snap = (event->xkey.state & ShiftMask) != 0;
|
2001-07-11 02:22:00 -04:00
|
|
|
|
|
|
|
#define SMALL_INCREMENT 1
|
|
|
|
#define NORMAL_INCREMENT 10
|
|
|
|
|
2001-08-19 14:09:10 -04:00
|
|
|
if (smart_snap)
|
|
|
|
incr = 0;
|
|
|
|
else if (event->xkey.state & ControlMask)
|
|
|
|
incr = SMALL_INCREMENT;
|
|
|
|
else
|
|
|
|
incr = NORMAL_INCREMENT;
|
2001-07-12 01:53:56 -04:00
|
|
|
|
2002-04-28 00:52:26 -04:00
|
|
|
/* When moving by increments, we still snap to edges if the move
|
|
|
|
* to the edge is smaller than the increment. This is because
|
|
|
|
* Shift + arrow to snap is sort of a hidden feature. This way
|
|
|
|
* people using just arrows shouldn't get too frustrated.
|
|
|
|
*/
|
2001-07-11 02:22:00 -04:00
|
|
|
|
2001-08-19 14:09:10 -04:00
|
|
|
switch (keysym)
|
|
|
|
{
|
|
|
|
case XK_Up:
|
|
|
|
case XK_KP_Up:
|
|
|
|
edge = meta_window_find_next_horizontal_edge (window, FALSE);
|
|
|
|
y -= incr;
|
2001-07-12 01:53:56 -04:00
|
|
|
|
2001-08-19 14:09:10 -04:00
|
|
|
if (smart_snap || ((edge > y) && ABS (edge - y) < incr))
|
|
|
|
y = edge;
|
2001-07-12 01:53:56 -04:00
|
|
|
|
2001-08-19 14:09:10 -04:00
|
|
|
handled = TRUE;
|
|
|
|
break;
|
|
|
|
case XK_Down:
|
|
|
|
case XK_KP_Down:
|
|
|
|
edge = meta_window_find_next_horizontal_edge (window, TRUE);
|
|
|
|
y += incr;
|
|
|
|
|
|
|
|
if (smart_snap || ((edge < y) && ABS (edge - y) < incr))
|
|
|
|
y = edge;
|
2001-07-12 01:53:56 -04:00
|
|
|
|
2001-08-19 14:09:10 -04:00
|
|
|
handled = TRUE;
|
|
|
|
break;
|
|
|
|
case XK_Left:
|
|
|
|
case XK_KP_Left:
|
|
|
|
edge = meta_window_find_next_vertical_edge (window, FALSE);
|
|
|
|
x -= incr;
|
2001-07-12 01:53:56 -04:00
|
|
|
|
2001-08-19 14:09:10 -04:00
|
|
|
if (smart_snap || ((edge > x) && ABS (edge - x) < incr))
|
|
|
|
x = edge;
|
|
|
|
|
|
|
|
handled = TRUE;
|
|
|
|
break;
|
|
|
|
case XK_Right:
|
|
|
|
case XK_KP_Right:
|
|
|
|
edge = meta_window_find_next_vertical_edge (window, TRUE);
|
|
|
|
x += incr;
|
|
|
|
if (smart_snap || ((edge < x) && ABS (edge - x) < incr))
|
|
|
|
x = edge;
|
|
|
|
handled = TRUE;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case XK_Escape:
|
|
|
|
/* End move and restore to original position */
|
|
|
|
meta_window_move_resize (display->grab_window,
|
2001-08-28 23:37:03 -04:00
|
|
|
TRUE,
|
2001-08-19 14:09:10 -04:00
|
|
|
display->grab_initial_window_pos.x,
|
|
|
|
display->grab_initial_window_pos.y,
|
|
|
|
display->grab_initial_window_pos.width,
|
|
|
|
display->grab_initial_window_pos.height);
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
2001-07-12 01:53:56 -04:00
|
|
|
|
2001-08-19 14:09:10 -04:00
|
|
|
if (handled)
|
Patch to provide extra cues to the user when using window menu move and
2002-08-08 Craig Black <blackc@speakeasy.net>
Patch to provide extra cues to the user when using
window menu move and resize, #85724.
* src/common.h: add new cursors
* src/display.c: (grab_op_is_mouse)
(meta_display_create_x_cursor), (xcursor_for_op),
(meta_display_set_grab_op_cursor),
(meta_display_begin_grab_op):
The keyboard move and resize grab ops now also use the mouse.
Allow the grab cursor to be changed during the grab op.
Hold onto the initial grab position in case of reset.
* src/display.h: save the initial grab position
* src/keybindings.c: (process_keyboard_move_grab),
(process_keyboard_resize_grab), (handle_begin_move),
(handle_begin_resize):
The keyboard move and resize grab ops now also use the mouse.
* src/window.c: (meta_window_client_message), (menu_callback),
(update_move), (update_resize),
(meta_window_handle_mouse_grab_op_event), (warp_pointer),
(meta_window_warp_pointer), (meta_window_begin_grab_op),
(meta_window_update_resize_grab_op):
When moving or resizing a window use the last grab position
in computing change increment.
Provide support for warping the mouse pointer.
* src/window.h: new warp pointer and grab op helper functions
2002-08-09 00:27:23 -04:00
|
|
|
{
|
|
|
|
meta_window_move (window, TRUE, x, y);
|
|
|
|
meta_window_warp_pointer (window, display->grab_op);
|
|
|
|
}
|
2001-07-11 02:22:00 -04:00
|
|
|
|
2001-08-19 14:09:10 -04:00
|
|
|
return handled;
|
|
|
|
}
|
|
|
|
|
2002-06-19 00:12:49 -04:00
|
|
|
static gboolean
|
|
|
|
process_keyboard_resize_grab (MetaDisplay *display,
|
2002-10-16 16:12:24 -04:00
|
|
|
MetaScreen *screen,
|
2002-06-19 00:12:49 -04:00
|
|
|
MetaWindow *window,
|
|
|
|
XEvent *event,
|
|
|
|
KeySym keysym)
|
|
|
|
{
|
|
|
|
gboolean handled;
|
|
|
|
int height_inc;
|
|
|
|
int width_inc;
|
|
|
|
int x, y;
|
|
|
|
int orig_x, orig_y;
|
|
|
|
int width, height;
|
|
|
|
gboolean smart_snap;
|
|
|
|
int edge;
|
|
|
|
int gravity;
|
|
|
|
|
|
|
|
handled = FALSE;
|
|
|
|
|
|
|
|
/* don't care about releases, but eat them, don't end grab */
|
|
|
|
if (event->type == KeyRelease)
|
|
|
|
return TRUE;
|
|
|
|
|
|
|
|
/* don't end grab on modifier key presses */
|
|
|
|
if (is_modifier (display, event->xkey.keycode))
|
|
|
|
return TRUE;
|
|
|
|
|
|
|
|
if (keysym == XK_Escape)
|
|
|
|
{
|
|
|
|
/* End resize and restore to original state */
|
|
|
|
meta_window_move_resize (display->grab_window,
|
|
|
|
TRUE,
|
|
|
|
display->grab_initial_window_pos.x,
|
|
|
|
display->grab_initial_window_pos.y,
|
|
|
|
display->grab_initial_window_pos.width,
|
|
|
|
display->grab_initial_window_pos.height);
|
|
|
|
|
Patch to provide extra cues to the user when using window menu move and
2002-08-08 Craig Black <blackc@speakeasy.net>
Patch to provide extra cues to the user when using
window menu move and resize, #85724.
* src/common.h: add new cursors
* src/display.c: (grab_op_is_mouse)
(meta_display_create_x_cursor), (xcursor_for_op),
(meta_display_set_grab_op_cursor),
(meta_display_begin_grab_op):
The keyboard move and resize grab ops now also use the mouse.
Allow the grab cursor to be changed during the grab op.
Hold onto the initial grab position in case of reset.
* src/display.h: save the initial grab position
* src/keybindings.c: (process_keyboard_move_grab),
(process_keyboard_resize_grab), (handle_begin_move),
(handle_begin_resize):
The keyboard move and resize grab ops now also use the mouse.
* src/window.c: (meta_window_client_message), (menu_callback),
(update_move), (update_resize),
(meta_window_handle_mouse_grab_op_event), (warp_pointer),
(meta_window_warp_pointer), (meta_window_begin_grab_op),
(meta_window_update_resize_grab_op):
When moving or resizing a window use the last grab position
in computing change increment.
Provide support for warping the mouse pointer.
* src/window.h: new warp pointer and grab op helper functions
2002-08-09 00:27:23 -04:00
|
|
|
return FALSE;
|
2002-06-19 00:12:49 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
switch (display->grab_op)
|
|
|
|
{
|
|
|
|
case META_GRAB_OP_KEYBOARD_RESIZING_UNKNOWN:
|
|
|
|
switch (keysym)
|
|
|
|
{
|
|
|
|
case XK_Up:
|
|
|
|
case XK_KP_Up:
|
|
|
|
display->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_N;
|
|
|
|
handled = TRUE;
|
|
|
|
break;
|
|
|
|
case XK_Down:
|
|
|
|
case XK_KP_Down:
|
|
|
|
display->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_S;
|
|
|
|
handled = TRUE;
|
|
|
|
break;
|
|
|
|
case XK_Left:
|
|
|
|
case XK_KP_Left:
|
|
|
|
display->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_W;
|
|
|
|
handled = TRUE;
|
|
|
|
break;
|
|
|
|
case XK_Right:
|
|
|
|
case XK_KP_Right:
|
|
|
|
display->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_E;
|
|
|
|
handled = TRUE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case META_GRAB_OP_KEYBOARD_RESIZING_S:
|
|
|
|
switch (keysym)
|
|
|
|
{
|
|
|
|
case XK_Left:
|
|
|
|
case XK_KP_Left:
|
|
|
|
display->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_SW;
|
|
|
|
handled = TRUE;
|
|
|
|
break;
|
|
|
|
case XK_Right:
|
|
|
|
case XK_KP_Right:
|
|
|
|
display->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_SE;
|
|
|
|
handled = TRUE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case META_GRAB_OP_KEYBOARD_RESIZING_N:
|
|
|
|
switch (keysym)
|
|
|
|
{
|
|
|
|
case XK_Left:
|
|
|
|
case XK_KP_Left:
|
|
|
|
display->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_NW;
|
|
|
|
handled = TRUE;
|
|
|
|
break;
|
|
|
|
case XK_Right:
|
|
|
|
case XK_KP_Right:
|
|
|
|
display->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_NE;
|
|
|
|
handled = TRUE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case META_GRAB_OP_KEYBOARD_RESIZING_W:
|
|
|
|
switch (keysym)
|
|
|
|
{
|
|
|
|
case XK_Up:
|
|
|
|
case XK_KP_Up:
|
|
|
|
display->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_NW;
|
|
|
|
handled = TRUE;
|
|
|
|
break;
|
|
|
|
case XK_Down:
|
|
|
|
case XK_KP_Down:
|
|
|
|
display->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_SW;
|
|
|
|
handled = TRUE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case META_GRAB_OP_KEYBOARD_RESIZING_E:
|
|
|
|
switch (keysym)
|
|
|
|
{
|
|
|
|
case XK_Up:
|
|
|
|
case XK_KP_Up:
|
|
|
|
display->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_NE;
|
|
|
|
handled = TRUE;
|
|
|
|
break;
|
|
|
|
case XK_Down:
|
|
|
|
case XK_KP_Down:
|
|
|
|
display->grab_op = META_GRAB_OP_KEYBOARD_RESIZING_SE;
|
|
|
|
handled = TRUE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case META_GRAB_OP_KEYBOARD_RESIZING_SE:
|
|
|
|
case META_GRAB_OP_KEYBOARD_RESIZING_NE:
|
|
|
|
case META_GRAB_OP_KEYBOARD_RESIZING_SW:
|
|
|
|
case META_GRAB_OP_KEYBOARD_RESIZING_NW:
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
g_assert_not_reached ();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (handled)
|
Patch to provide extra cues to the user when using window menu move and
2002-08-08 Craig Black <blackc@speakeasy.net>
Patch to provide extra cues to the user when using
window menu move and resize, #85724.
* src/common.h: add new cursors
* src/display.c: (grab_op_is_mouse)
(meta_display_create_x_cursor), (xcursor_for_op),
(meta_display_set_grab_op_cursor),
(meta_display_begin_grab_op):
The keyboard move and resize grab ops now also use the mouse.
Allow the grab cursor to be changed during the grab op.
Hold onto the initial grab position in case of reset.
* src/display.h: save the initial grab position
* src/keybindings.c: (process_keyboard_move_grab),
(process_keyboard_resize_grab), (handle_begin_move),
(handle_begin_resize):
The keyboard move and resize grab ops now also use the mouse.
* src/window.c: (meta_window_client_message), (menu_callback),
(update_move), (update_resize),
(meta_window_handle_mouse_grab_op_event), (warp_pointer),
(meta_window_warp_pointer), (meta_window_begin_grab_op),
(meta_window_update_resize_grab_op):
When moving or resizing a window use the last grab position
in computing change increment.
Provide support for warping the mouse pointer.
* src/window.h: new warp pointer and grab op helper functions
2002-08-09 00:27:23 -04:00
|
|
|
{
|
|
|
|
meta_window_update_resize_grab_op (window, TRUE);
|
|
|
|
return TRUE;
|
|
|
|
}
|
2002-06-19 00:12:49 -04:00
|
|
|
|
|
|
|
meta_window_get_position (window, &orig_x, &orig_y);
|
|
|
|
x = orig_x;
|
|
|
|
y = orig_y;
|
|
|
|
width = window->rect.width;
|
|
|
|
height = window->rect.height;
|
|
|
|
|
|
|
|
gravity = meta_resize_gravity_from_grab_op (display->grab_op);
|
|
|
|
|
|
|
|
smart_snap = (event->xkey.state & ShiftMask) != 0;
|
|
|
|
|
|
|
|
#define SMALL_INCREMENT 1
|
|
|
|
#define NORMAL_INCREMENT 10
|
|
|
|
|
|
|
|
if (smart_snap)
|
|
|
|
{
|
|
|
|
height_inc = 0;
|
|
|
|
width_inc = 0;
|
|
|
|
}
|
|
|
|
else if (event->xkey.state & ControlMask)
|
|
|
|
{
|
|
|
|
if (window->size_hints.width_inc > 1)
|
|
|
|
width_inc = window->size_hints.width_inc;
|
|
|
|
else
|
|
|
|
width_inc = SMALL_INCREMENT;
|
|
|
|
|
|
|
|
if (window->size_hints.height_inc > 1)
|
|
|
|
height_inc = window->size_hints.height_inc;
|
|
|
|
else
|
|
|
|
height_inc = SMALL_INCREMENT;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (window->size_hints.width_inc > 1)
|
|
|
|
width_inc = window->size_hints.width_inc;
|
|
|
|
else
|
|
|
|
width_inc = NORMAL_INCREMENT;
|
|
|
|
|
|
|
|
if (window->size_hints.height_inc > 1)
|
|
|
|
height_inc = window->size_hints.height_inc;
|
|
|
|
else
|
|
|
|
height_inc = NORMAL_INCREMENT;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* When moving by increments, we still snap to edges if the move
|
|
|
|
* to the edge is smaller than the increment. This is because
|
|
|
|
* Shift + arrow to snap is sort of a hidden feature. This way
|
|
|
|
* people using just arrows shouldn't get too frustrated.
|
|
|
|
*/
|
|
|
|
|
|
|
|
switch (keysym)
|
|
|
|
{
|
|
|
|
case XK_Up:
|
|
|
|
case XK_KP_Up:
|
|
|
|
switch (gravity)
|
|
|
|
{
|
|
|
|
case NorthGravity:
|
|
|
|
case NorthWestGravity:
|
|
|
|
case NorthEastGravity:
|
|
|
|
/* Move bottom edge up */
|
|
|
|
edge = meta_window_find_next_horizontal_edge (window, TRUE);
|
|
|
|
height -= height_inc;
|
|
|
|
|
|
|
|
if (smart_snap || ((edge > (y+height)) &&
|
|
|
|
ABS (edge - (y+height)) < height_inc))
|
|
|
|
height = edge - y;
|
|
|
|
|
|
|
|
handled = TRUE;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case SouthGravity:
|
|
|
|
case SouthWestGravity:
|
|
|
|
case SouthEastGravity:
|
|
|
|
/* Move top edge up */
|
|
|
|
edge = meta_window_find_next_horizontal_edge (window, FALSE);
|
|
|
|
y -= height_inc;
|
|
|
|
|
|
|
|
if (smart_snap || ((edge > y) && ABS (edge - y) < height_inc))
|
|
|
|
y = edge;
|
|
|
|
|
|
|
|
height += (orig_y - y);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case EastGravity:
|
|
|
|
case WestGravity:
|
|
|
|
case CenterGravity:
|
|
|
|
g_assert_not_reached ();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
handled = TRUE;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case XK_Down:
|
|
|
|
case XK_KP_Down:
|
|
|
|
switch (gravity)
|
|
|
|
{
|
|
|
|
case NorthGravity:
|
|
|
|
case NorthWestGravity:
|
|
|
|
case NorthEastGravity:
|
|
|
|
/* Move bottom edge down */
|
|
|
|
edge = meta_window_find_next_horizontal_edge (window, TRUE);
|
|
|
|
height += height_inc;
|
|
|
|
|
|
|
|
if (smart_snap || ((edge < (y+height)) &&
|
|
|
|
ABS (edge - (y+height)) < height_inc))
|
|
|
|
height = edge - y;
|
|
|
|
|
|
|
|
handled = TRUE;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case SouthGravity:
|
|
|
|
case SouthWestGravity:
|
|
|
|
case SouthEastGravity:
|
|
|
|
/* Move top edge down */
|
|
|
|
edge = meta_window_find_next_horizontal_edge (window, FALSE);
|
|
|
|
y += height_inc;
|
|
|
|
|
|
|
|
if (smart_snap || ((edge < y) && ABS (edge - y) < height_inc))
|
|
|
|
y = edge;
|
|
|
|
|
|
|
|
height -= (y - orig_y);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case EastGravity:
|
|
|
|
case WestGravity:
|
|
|
|
case CenterGravity:
|
|
|
|
g_assert_not_reached ();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
handled = TRUE;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case XK_Left:
|
|
|
|
case XK_KP_Left:
|
2002-07-02 22:32:40 -04:00
|
|
|
switch (gravity)
|
|
|
|
{
|
|
|
|
case EastGravity:
|
|
|
|
case SouthEastGravity:
|
|
|
|
case NorthEastGravity:
|
|
|
|
/* Move left edge left */
|
|
|
|
edge = meta_window_find_next_vertical_edge (window, TRUE);
|
|
|
|
x -= width_inc;
|
|
|
|
|
|
|
|
if (smart_snap || ((edge > x) && ABS (edge - x) < width_inc))
|
|
|
|
x = edge;
|
|
|
|
|
|
|
|
width += (orig_x - x);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case WestGravity:
|
|
|
|
case SouthWestGravity:
|
|
|
|
case NorthWestGravity:
|
|
|
|
/* Move right edge left */
|
|
|
|
edge = meta_window_find_next_vertical_edge (window, FALSE);
|
|
|
|
width -= width_inc;
|
|
|
|
|
|
|
|
if (smart_snap || ((edge > (x+width)) &&
|
|
|
|
ABS (edge - (x+width)) < width_inc))
|
|
|
|
width = edge - x;
|
|
|
|
|
|
|
|
handled = TRUE;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case NorthGravity:
|
|
|
|
case SouthGravity:
|
|
|
|
case CenterGravity:
|
|
|
|
g_assert_not_reached ();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
handled = TRUE;
|
2002-06-19 00:12:49 -04:00
|
|
|
break;
|
2002-07-02 22:32:40 -04:00
|
|
|
|
2002-06-19 00:12:49 -04:00
|
|
|
case XK_Right:
|
|
|
|
case XK_KP_Right:
|
2002-07-02 22:32:40 -04:00
|
|
|
switch (gravity)
|
|
|
|
{
|
|
|
|
case EastGravity:
|
|
|
|
case SouthEastGravity:
|
|
|
|
case NorthEastGravity:
|
|
|
|
/* Move left edge right */
|
|
|
|
edge = meta_window_find_next_vertical_edge (window, FALSE);
|
|
|
|
x += width_inc;
|
|
|
|
|
|
|
|
if (smart_snap || ((edge < x) && ABS (edge - x) < width_inc))
|
|
|
|
x = edge;
|
|
|
|
|
|
|
|
width -= (x - orig_x);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case WestGravity:
|
|
|
|
case SouthWestGravity:
|
|
|
|
case NorthWestGravity:
|
|
|
|
/* Move right edge right */
|
|
|
|
edge = meta_window_find_next_vertical_edge (window, TRUE);
|
|
|
|
width += width_inc;
|
|
|
|
|
|
|
|
if (smart_snap || ((edge > (x+width)) &&
|
|
|
|
ABS (edge - (x+width)) < width_inc))
|
|
|
|
width = edge - x;
|
|
|
|
|
|
|
|
handled = TRUE;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case NorthGravity:
|
|
|
|
case SouthGravity:
|
|
|
|
case CenterGravity:
|
|
|
|
g_assert_not_reached ();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
handled = TRUE;
|
2002-06-19 00:12:49 -04:00
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* fixup hack (just paranoia, not sure it's required) */
|
|
|
|
if (height < 1)
|
|
|
|
height = 1;
|
|
|
|
if (width < 1)
|
|
|
|
width = 1;
|
|
|
|
|
|
|
|
if (handled)
|
Patch to provide extra cues to the user when using window menu move and
2002-08-08 Craig Black <blackc@speakeasy.net>
Patch to provide extra cues to the user when using
window menu move and resize, #85724.
* src/common.h: add new cursors
* src/display.c: (grab_op_is_mouse)
(meta_display_create_x_cursor), (xcursor_for_op),
(meta_display_set_grab_op_cursor),
(meta_display_begin_grab_op):
The keyboard move and resize grab ops now also use the mouse.
Allow the grab cursor to be changed during the grab op.
Hold onto the initial grab position in case of reset.
* src/display.h: save the initial grab position
* src/keybindings.c: (process_keyboard_move_grab),
(process_keyboard_resize_grab), (handle_begin_move),
(handle_begin_resize):
The keyboard move and resize grab ops now also use the mouse.
* src/window.c: (meta_window_client_message), (menu_callback),
(update_move), (update_resize),
(meta_window_handle_mouse_grab_op_event), (warp_pointer),
(meta_window_warp_pointer), (meta_window_begin_grab_op),
(meta_window_update_resize_grab_op):
When moving or resizing a window use the last grab position
in computing change increment.
Provide support for warping the mouse pointer.
* src/window.h: new warp pointer and grab op helper functions
2002-08-09 00:27:23 -04:00
|
|
|
{
|
|
|
|
meta_window_move_resize (window, TRUE, x, y, width, height);
|
|
|
|
meta_window_update_resize_grab_op (window, FALSE);
|
|
|
|
}
|
2002-06-19 00:12:49 -04:00
|
|
|
|
|
|
|
return handled;
|
|
|
|
}
|
|
|
|
|
2001-08-19 14:09:10 -04:00
|
|
|
static gboolean
|
|
|
|
process_tab_grab (MetaDisplay *display,
|
2002-10-16 16:12:24 -04:00
|
|
|
MetaScreen *screen,
|
2001-08-19 14:09:10 -04:00
|
|
|
XEvent *event,
|
|
|
|
KeySym keysym)
|
|
|
|
{
|
2002-06-08 23:44:16 -04:00
|
|
|
MetaKeyBindingAction action;
|
2002-07-06 12:50:48 -04:00
|
|
|
gboolean popup_not_showing;
|
2002-10-18 18:19:05 -04:00
|
|
|
gboolean backward;
|
|
|
|
gboolean key_used;
|
2002-10-16 16:12:24 -04:00
|
|
|
|
|
|
|
if (screen != display->grab_screen)
|
|
|
|
return FALSE;
|
2001-08-19 14:09:10 -04:00
|
|
|
|
|
|
|
g_return_val_if_fail (screen->tab_popup != NULL, FALSE);
|
2001-07-25 23:14:45 -04:00
|
|
|
|
2001-08-19 14:09:10 -04:00
|
|
|
if (event->type == KeyRelease &&
|
2002-04-28 00:52:26 -04:00
|
|
|
keycode_is_primary_modifier (display, event->xkey.keycode,
|
|
|
|
display->grab_mask))
|
2001-07-11 02:22:00 -04:00
|
|
|
{
|
2001-08-19 14:09:10 -04:00
|
|
|
/* We're done, move to the new window. */
|
|
|
|
Window target_xwindow;
|
|
|
|
MetaWindow *target_window;
|
|
|
|
|
|
|
|
target_xwindow =
|
2002-06-08 23:44:16 -04:00
|
|
|
(Window) meta_ui_tab_popup_get_selected (screen->tab_popup);
|
2001-08-19 14:09:10 -04:00
|
|
|
target_window =
|
|
|
|
meta_display_lookup_x_window (display, target_xwindow);
|
|
|
|
|
2002-04-28 00:52:26 -04:00
|
|
|
meta_topic (META_DEBUG_KEYBINDINGS,
|
|
|
|
"Ending tab operation, primary modifier released\n");
|
2001-08-19 14:09:10 -04:00
|
|
|
|
|
|
|
if (target_window)
|
|
|
|
{
|
2002-04-28 00:52:26 -04:00
|
|
|
meta_topic (META_DEBUG_KEYBINDINGS,
|
|
|
|
"Ending grab early so we can focus the target window\n");
|
2001-08-19 14:09:10 -04:00
|
|
|
meta_display_end_grab_op (display, event->xkey.time);
|
|
|
|
|
2002-04-28 00:52:26 -04:00
|
|
|
meta_topic (META_DEBUG_KEYBINDINGS,
|
|
|
|
"Activating target window\n");
|
2001-10-29 02:00:46 -05:00
|
|
|
|
2002-01-03 18:28:19 -05:00
|
|
|
meta_topic (META_DEBUG_FOCUS, "Activating %s due to tab popup selection\n",
|
|
|
|
target_window->desc);
|
2001-10-29 02:00:46 -05:00
|
|
|
meta_window_activate (target_window, event->xkey.time);
|
2001-08-19 14:09:10 -04:00
|
|
|
|
|
|
|
return TRUE; /* we already ended the grab */
|
|
|
|
}
|
|
|
|
|
|
|
|
return FALSE; /* end grab */
|
|
|
|
}
|
|
|
|
|
|
|
|
/* don't care about other releases, but eat them, don't end grab */
|
|
|
|
if (event->type == KeyRelease)
|
|
|
|
return TRUE;
|
|
|
|
|
|
|
|
/* don't end grab on modifier key presses */
|
|
|
|
if (is_modifier (display, event->xkey.keycode))
|
|
|
|
return TRUE;
|
|
|
|
|
2002-07-13 23:16:41 -04:00
|
|
|
action = display_get_keybinding_action (display,
|
|
|
|
keysym,
|
|
|
|
display->grab_mask);
|
2002-06-08 23:44:16 -04:00
|
|
|
|
2002-07-06 12:50:48 -04:00
|
|
|
/* FIXME weird side effect here is that you can use the Escape
|
|
|
|
* key while tabbing, or the tab key while escaping
|
|
|
|
*/
|
|
|
|
|
|
|
|
popup_not_showing = FALSE;
|
2002-10-18 18:19:05 -04:00
|
|
|
key_used = FALSE;
|
|
|
|
backward = FALSE;
|
|
|
|
|
2002-06-08 23:44:16 -04:00
|
|
|
switch (action)
|
2001-08-19 14:09:10 -04:00
|
|
|
{
|
2002-07-06 12:50:48 -04:00
|
|
|
case META_KEYBINDING_ACTION_CYCLE_PANELS:
|
|
|
|
case META_KEYBINDING_ACTION_CYCLE_WINDOWS:
|
|
|
|
popup_not_showing = TRUE;
|
2002-10-18 18:19:05 -04:00
|
|
|
key_used = TRUE;
|
|
|
|
break;
|
|
|
|
case META_KEYBINDING_ACTION_CYCLE_PANELS_BACKWARD:
|
|
|
|
case META_KEYBINDING_ACTION_CYCLE_WINDOWS_BACKWARD:
|
|
|
|
popup_not_showing = TRUE;
|
|
|
|
key_used = TRUE;
|
|
|
|
backward = TRUE;
|
|
|
|
break;
|
2002-06-08 23:44:16 -04:00
|
|
|
case META_KEYBINDING_ACTION_SWITCH_PANELS:
|
|
|
|
case META_KEYBINDING_ACTION_SWITCH_WINDOWS:
|
2002-10-18 18:19:05 -04:00
|
|
|
key_used = TRUE;
|
|
|
|
break;
|
|
|
|
case META_KEYBINDING_ACTION_SWITCH_PANELS_BACKWARD:
|
|
|
|
case META_KEYBINDING_ACTION_SWITCH_WINDOWS_BACKWARD:
|
|
|
|
key_used = TRUE;
|
|
|
|
backward = TRUE;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (key_used)
|
|
|
|
{
|
2002-07-06 12:50:48 -04:00
|
|
|
meta_topic (META_DEBUG_KEYBINDINGS,
|
|
|
|
"Key pressed, moving tab focus in popup\n");
|
|
|
|
|
2001-08-19 14:09:10 -04:00
|
|
|
if (event->xkey.state & ShiftMask)
|
2002-10-18 18:19:05 -04:00
|
|
|
backward = !backward;
|
|
|
|
|
|
|
|
if (backward)
|
2001-08-19 14:09:10 -04:00
|
|
|
meta_ui_tab_popup_backward (screen->tab_popup);
|
|
|
|
else
|
|
|
|
meta_ui_tab_popup_forward (screen->tab_popup);
|
2002-10-18 18:19:05 -04:00
|
|
|
|
2002-07-06 12:50:48 -04:00
|
|
|
if (popup_not_showing)
|
|
|
|
{
|
|
|
|
/* We can't actually change window focus, due to the grab.
|
|
|
|
* but raise the window.
|
|
|
|
*/
|
|
|
|
Window target_xwindow;
|
|
|
|
MetaWindow *target_window;
|
|
|
|
|
|
|
|
target_xwindow =
|
|
|
|
(Window) meta_ui_tab_popup_get_selected (screen->tab_popup);
|
|
|
|
target_window =
|
|
|
|
meta_display_lookup_x_window (display, target_xwindow);
|
|
|
|
|
|
|
|
if (target_window)
|
|
|
|
{
|
|
|
|
meta_window_raise (target_window);
|
|
|
|
}
|
|
|
|
}
|
2001-07-11 02:22:00 -04:00
|
|
|
}
|
2002-10-18 18:19:05 -04:00
|
|
|
else
|
|
|
|
{
|
|
|
|
/* end grab */
|
|
|
|
meta_topic (META_DEBUG_KEYBINDINGS,
|
|
|
|
"Ending tabbing/cycling, uninteresting key pressed\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
return key_used;
|
2001-06-23 01:49:35 -04:00
|
|
|
}
|
2001-06-06 00:47:37 -04:00
|
|
|
|
2001-08-03 09:56:39 -04:00
|
|
|
static void
|
|
|
|
switch_to_workspace (MetaDisplay *display,
|
|
|
|
MetaWorkspace *workspace)
|
|
|
|
{
|
|
|
|
MetaWindow *move_window;
|
|
|
|
|
|
|
|
move_window = NULL;
|
|
|
|
if (display->grab_op == META_GRAB_OP_MOVING)
|
|
|
|
move_window = display->grab_window;
|
|
|
|
|
|
|
|
if (move_window != NULL)
|
|
|
|
{
|
|
|
|
if (move_window->on_all_workspaces)
|
|
|
|
move_window = NULL; /* don't move it after all */
|
|
|
|
|
|
|
|
/* We put the window on the new workspace, flip spaces,
|
|
|
|
* then remove from old workspace, so the window
|
|
|
|
* never gets unmapped and we maintain the button grab
|
|
|
|
* on it.
|
|
|
|
*/
|
|
|
|
if (move_window)
|
|
|
|
{
|
|
|
|
if (!meta_workspace_contains_window (workspace,
|
|
|
|
move_window))
|
|
|
|
meta_workspace_add_window (workspace, move_window);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
meta_workspace_activate (workspace);
|
|
|
|
|
|
|
|
if (move_window)
|
|
|
|
{
|
2002-08-06 00:11:23 -04:00
|
|
|
/* Removes window from other spaces */
|
|
|
|
meta_window_change_workspace (move_window, workspace);
|
2002-08-10 13:17:58 -04:00
|
|
|
meta_window_raise (move_window);
|
2001-08-03 09:56:39 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2001-06-06 00:47:37 -04:00
|
|
|
static void
|
2002-04-28 00:52:26 -04:00
|
|
|
handle_activate_workspace (MetaDisplay *display,
|
2002-10-16 16:12:24 -04:00
|
|
|
MetaScreen *screen,
|
2002-04-28 00:52:26 -04:00
|
|
|
MetaWindow *event_window,
|
|
|
|
XEvent *event,
|
|
|
|
MetaKeyBinding *binding)
|
2001-06-06 00:47:37 -04:00
|
|
|
{
|
|
|
|
int which;
|
|
|
|
MetaWorkspace *workspace;
|
|
|
|
|
2002-04-28 00:52:26 -04:00
|
|
|
which = GPOINTER_TO_INT (binding->handler->data);
|
2002-06-08 23:44:16 -04:00
|
|
|
|
2002-04-28 00:52:26 -04:00
|
|
|
workspace = NULL;
|
|
|
|
if (which < 0)
|
2002-10-16 16:12:24 -04:00
|
|
|
{
|
2002-04-28 00:52:26 -04:00
|
|
|
workspace = meta_workspace_get_neighbor (screen->active_workspace,
|
|
|
|
which);
|
2001-08-03 09:56:39 -04:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2002-10-16 16:12:24 -04:00
|
|
|
workspace = meta_screen_get_workspace_by_index (screen, which);
|
2001-08-03 09:56:39 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
if (workspace)
|
|
|
|
{
|
|
|
|
switch_to_workspace (display, workspace);
|
2001-06-06 00:47:37 -04:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* We could offer to create it I suppose */
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2002-07-11 00:10:44 -04:00
|
|
|
static void
|
|
|
|
error_on_command (int command_index,
|
|
|
|
const char *command,
|
|
|
|
const char *message)
|
|
|
|
{
|
|
|
|
GError *err;
|
|
|
|
char *argv[6];
|
|
|
|
char *key;
|
|
|
|
|
|
|
|
meta_warning ("Error on command %d \"%s\": %s\n",
|
|
|
|
command_index, command, message);
|
|
|
|
|
|
|
|
key = meta_prefs_get_gconf_key_for_command (command_index);
|
|
|
|
|
|
|
|
argv[0] = METACITY_LIBEXECDIR"/metacity-dialog";
|
|
|
|
argv[1] = "--command-failed-error";
|
|
|
|
argv[2] = key;
|
|
|
|
argv[3] = (char*) (command ? command : "");
|
|
|
|
argv[4] = (char*) message;
|
|
|
|
argv[5] = NULL;
|
|
|
|
|
|
|
|
err = NULL;
|
|
|
|
if (!g_spawn_async_with_pipes ("/",
|
|
|
|
argv,
|
|
|
|
NULL,
|
|
|
|
0,
|
|
|
|
NULL, NULL,
|
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
&err))
|
|
|
|
{
|
|
|
|
meta_warning (_("Error launching metacity-dialog to print an error about a command: %s\n"),
|
|
|
|
err->message);
|
|
|
|
g_error_free (err);
|
|
|
|
}
|
|
|
|
|
|
|
|
g_free (key);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
handle_run_command (MetaDisplay *display,
|
2002-10-16 16:12:24 -04:00
|
|
|
MetaScreen *screen,
|
2002-07-11 00:10:44 -04:00
|
|
|
MetaWindow *window,
|
|
|
|
XEvent *event,
|
|
|
|
MetaKeyBinding *binding)
|
|
|
|
{
|
|
|
|
int which;
|
|
|
|
const char *command;
|
|
|
|
GError *err;
|
|
|
|
|
|
|
|
which = GPOINTER_TO_INT (binding->handler->data);
|
|
|
|
|
|
|
|
command = meta_prefs_get_command (which);
|
|
|
|
|
|
|
|
if (command == NULL)
|
|
|
|
{
|
|
|
|
char *s;
|
|
|
|
|
|
|
|
meta_topic (META_DEBUG_KEYBINDINGS,
|
|
|
|
"No command %d to run in response to keybinding press\n",
|
|
|
|
which);
|
|
|
|
|
|
|
|
s = g_strdup_printf (_("No command %d has been defined.\n"),
|
|
|
|
which + 1);
|
|
|
|
error_on_command (which, NULL, s);
|
|
|
|
g_free (s);
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
err = NULL;
|
|
|
|
if (!g_spawn_command_line_async (command, &err))
|
|
|
|
{
|
|
|
|
error_on_command (which, command, err->message);
|
|
|
|
|
|
|
|
g_error_free (err);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2002-12-08 16:09:05 -05:00
|
|
|
|
|
|
|
static void
|
|
|
|
handle_maximize_vert (MetaDisplay *display,
|
|
|
|
MetaScreen *screen,
|
|
|
|
MetaWindow *window,
|
|
|
|
XEvent *event,
|
|
|
|
MetaKeyBinding *binding)
|
|
|
|
{
|
|
|
|
if (window)
|
|
|
|
{
|
|
|
|
if (window->has_resize_func)
|
|
|
|
meta_window_fill_vertical (window);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
handle_maximize_horiz (MetaDisplay *display,
|
|
|
|
MetaScreen *screen,
|
|
|
|
MetaWindow *window,
|
|
|
|
XEvent *event,
|
|
|
|
MetaKeyBinding *binding)
|
|
|
|
{
|
|
|
|
if (window)
|
|
|
|
{
|
|
|
|
if (window->has_resize_func)
|
|
|
|
meta_window_fill_horizontal (window);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2002-06-08 23:44:16 -04:00
|
|
|
static gboolean
|
2002-06-09 00:04:19 -04:00
|
|
|
process_workspace_switch_grab (MetaDisplay *display,
|
2002-10-16 16:12:24 -04:00
|
|
|
MetaScreen *screen,
|
2002-06-09 00:04:19 -04:00
|
|
|
XEvent *event,
|
|
|
|
KeySym keysym)
|
2002-06-08 23:44:16 -04:00
|
|
|
{
|
|
|
|
MetaWorkspace *workspace;
|
|
|
|
|
2002-10-16 16:12:24 -04:00
|
|
|
if (screen != display->grab_screen)
|
|
|
|
return FALSE;
|
2002-06-08 23:44:16 -04:00
|
|
|
|
|
|
|
g_return_val_if_fail (screen->tab_popup != NULL, FALSE);
|
|
|
|
|
|
|
|
if (event->type == KeyRelease &&
|
|
|
|
keycode_is_primary_modifier (display, event->xkey.keycode,
|
|
|
|
display->grab_mask))
|
|
|
|
{
|
|
|
|
/* We're done, move to the new workspace. */
|
|
|
|
MetaWorkspace *target_workspace;
|
|
|
|
|
|
|
|
target_workspace =
|
|
|
|
(MetaWorkspace *) meta_ui_tab_popup_get_selected (screen->tab_popup);
|
|
|
|
|
|
|
|
meta_topic (META_DEBUG_KEYBINDINGS,
|
|
|
|
"Ending workspace tab operation, primary modifier released\n");
|
|
|
|
if (target_workspace)
|
|
|
|
{
|
|
|
|
meta_topic (META_DEBUG_KEYBINDINGS,
|
|
|
|
"Ending grab early so we can focus the target workspace\n");
|
|
|
|
meta_display_end_grab_op (display, event->xkey.time);
|
|
|
|
|
|
|
|
meta_topic (META_DEBUG_KEYBINDINGS,
|
|
|
|
"Activating target workspace\n");
|
|
|
|
|
|
|
|
switch_to_workspace (display, target_workspace);
|
|
|
|
|
|
|
|
return TRUE; /* we already ended the grab */
|
|
|
|
}
|
|
|
|
|
|
|
|
return FALSE; /* end grab */
|
|
|
|
}
|
|
|
|
|
|
|
|
/* don't care about other releases, but eat them, don't end grab */
|
|
|
|
if (event->type == KeyRelease)
|
|
|
|
return TRUE;
|
|
|
|
|
|
|
|
/* don't end grab on modifier key presses */
|
|
|
|
if (is_modifier (display, event->xkey.keycode))
|
|
|
|
return TRUE;
|
|
|
|
|
|
|
|
/* select the next workspace in the tabpopup */
|
|
|
|
workspace =
|
|
|
|
(MetaWorkspace *) meta_ui_tab_popup_get_selected (screen->tab_popup);
|
|
|
|
|
|
|
|
if (workspace)
|
|
|
|
{
|
|
|
|
MetaWorkspace *target_workspace;
|
|
|
|
MetaKeyBindingAction action;
|
|
|
|
|
2002-07-13 23:16:41 -04:00
|
|
|
action = display_get_keybinding_action (display,
|
|
|
|
keysym,
|
|
|
|
display->grab_mask);
|
2002-06-08 23:44:16 -04:00
|
|
|
|
|
|
|
switch (action)
|
|
|
|
{
|
|
|
|
case META_KEYBINDING_ACTION_WORKSPACE_UP:
|
|
|
|
target_workspace = meta_workspace_get_neighbor (workspace,
|
|
|
|
META_MOTION_UP);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case META_KEYBINDING_ACTION_WORKSPACE_DOWN:
|
|
|
|
target_workspace = meta_workspace_get_neighbor (workspace,
|
|
|
|
META_MOTION_DOWN);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case META_KEYBINDING_ACTION_WORKSPACE_LEFT:
|
|
|
|
target_workspace = meta_workspace_get_neighbor (workspace,
|
|
|
|
META_MOTION_LEFT);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case META_KEYBINDING_ACTION_WORKSPACE_RIGHT:
|
|
|
|
target_workspace = meta_workspace_get_neighbor (workspace,
|
|
|
|
META_MOTION_RIGHT);
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
target_workspace = NULL;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (target_workspace)
|
|
|
|
{
|
|
|
|
meta_ui_tab_popup_select (screen->tab_popup,
|
|
|
|
(MetaTabEntryKey) target_workspace);
|
|
|
|
meta_topic (META_DEBUG_KEYBINDINGS,
|
|
|
|
"Tab key pressed, moving tab focus in popup\n");
|
2002-09-09 14:16:25 -04:00
|
|
|
|
|
|
|
meta_topic (META_DEBUG_KEYBINDINGS,
|
|
|
|
"Activating target workspace\n");
|
|
|
|
|
|
|
|
switch_to_workspace (display, target_workspace);
|
|
|
|
|
|
|
|
return TRUE; /* we already ended the grab */
|
2002-06-08 23:44:16 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* end grab */
|
|
|
|
meta_topic (META_DEBUG_KEYBINDINGS,
|
|
|
|
"Ending workspace tabbing, uninteresting key pressed\n");
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2001-10-14 23:39:41 -04:00
|
|
|
static void
|
2002-04-28 00:52:26 -04:00
|
|
|
handle_toggle_desktop (MetaDisplay *display,
|
2002-10-16 16:12:24 -04:00
|
|
|
MetaScreen *screen,
|
2002-04-28 00:52:26 -04:00
|
|
|
MetaWindow *window,
|
|
|
|
XEvent *event,
|
|
|
|
MetaKeyBinding *binding)
|
2001-10-14 23:39:41 -04:00
|
|
|
{
|
2002-10-16 16:12:24 -04:00
|
|
|
if (screen->showing_desktop)
|
|
|
|
meta_screen_unshow_desktop (screen);
|
2001-10-14 23:39:41 -04:00
|
|
|
else
|
2002-10-16 16:12:24 -04:00
|
|
|
meta_screen_show_desktop (screen);
|
2001-10-14 23:39:41 -04:00
|
|
|
}
|
|
|
|
|
2001-06-23 01:49:35 -04:00
|
|
|
static void
|
2002-04-28 00:52:26 -04:00
|
|
|
handle_activate_menu (MetaDisplay *display,
|
2002-10-16 16:12:24 -04:00
|
|
|
MetaScreen *screen,
|
2002-04-28 00:52:26 -04:00
|
|
|
MetaWindow *event_window,
|
|
|
|
XEvent *event,
|
|
|
|
MetaKeyBinding *binding)
|
2001-06-23 01:49:35 -04:00
|
|
|
{
|
|
|
|
if (display->focus_window)
|
|
|
|
{
|
|
|
|
int x, y;
|
|
|
|
|
|
|
|
meta_window_get_position (display->focus_window,
|
|
|
|
&x, &y);
|
|
|
|
|
|
|
|
meta_window_show_menu (display->focus_window,
|
|
|
|
x, y,
|
|
|
|
0,
|
|
|
|
event->xkey.time);
|
|
|
|
}
|
|
|
|
}
|
2001-06-23 22:22:10 -04:00
|
|
|
|
2002-04-05 10:52:49 -05:00
|
|
|
static MetaGrabOp
|
2002-07-06 12:50:48 -04:00
|
|
|
tab_op_from_tab_type (MetaTabList type)
|
2002-04-05 10:52:49 -05:00
|
|
|
{
|
|
|
|
switch (type)
|
|
|
|
{
|
|
|
|
case META_TAB_LIST_NORMAL:
|
|
|
|
return META_GRAB_OP_KEYBOARD_TABBING_NORMAL;
|
|
|
|
case META_TAB_LIST_DOCKS:
|
|
|
|
return META_GRAB_OP_KEYBOARD_TABBING_DOCK;
|
|
|
|
}
|
|
|
|
|
|
|
|
g_assert_not_reached ();
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2002-07-06 12:50:48 -04:00
|
|
|
static MetaGrabOp
|
|
|
|
cycle_op_from_tab_type (MetaTabList type)
|
|
|
|
{
|
|
|
|
switch (type)
|
|
|
|
{
|
|
|
|
case META_TAB_LIST_NORMAL:
|
|
|
|
return META_GRAB_OP_KEYBOARD_ESCAPING_NORMAL;
|
|
|
|
case META_TAB_LIST_DOCKS:
|
|
|
|
return META_GRAB_OP_KEYBOARD_ESCAPING_DOCK;
|
|
|
|
}
|
|
|
|
|
|
|
|
g_assert_not_reached ();
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2001-06-23 22:22:10 -04:00
|
|
|
static void
|
2002-07-06 12:50:48 -04:00
|
|
|
do_choose_window (MetaDisplay *display,
|
2002-10-16 16:12:24 -04:00
|
|
|
MetaScreen *screen,
|
2002-07-06 12:50:48 -04:00
|
|
|
MetaWindow *event_window,
|
|
|
|
XEvent *event,
|
|
|
|
MetaKeyBinding *binding,
|
2002-10-18 18:19:05 -04:00
|
|
|
gboolean backward,
|
2002-07-06 12:50:48 -04:00
|
|
|
gboolean show_popup)
|
2001-06-23 22:22:10 -04:00
|
|
|
{
|
2002-04-05 10:52:49 -05:00
|
|
|
MetaTabList type;
|
2002-09-04 00:15:46 -04:00
|
|
|
MetaWindow *initial_selection;
|
2001-06-23 23:18:10 -04:00
|
|
|
|
2002-04-28 00:52:26 -04:00
|
|
|
type = GPOINTER_TO_INT (binding->handler->data);
|
2001-06-23 22:22:10 -04:00
|
|
|
|
2002-04-28 00:52:26 -04:00
|
|
|
meta_topic (META_DEBUG_KEYBINDINGS,
|
2002-07-06 12:50:48 -04:00
|
|
|
"Tab list = %d show_popup = %d\n", type, show_popup);
|
2002-10-16 16:12:24 -04:00
|
|
|
|
2002-10-18 18:19:05 -04:00
|
|
|
/* reverse direction if shift is down */
|
|
|
|
if (event->xkey.state & ShiftMask)
|
|
|
|
backward = !backward;
|
|
|
|
|
2002-09-04 00:15:46 -04:00
|
|
|
initial_selection = meta_display_get_tab_next (display,
|
|
|
|
type,
|
|
|
|
screen,
|
|
|
|
screen->active_workspace,
|
|
|
|
NULL,
|
|
|
|
backward);
|
2002-07-06 12:50:48 -04:00
|
|
|
|
2002-09-04 00:15:46 -04:00
|
|
|
/* Note that focus_window may not be in the tab chain, but it's OK */
|
|
|
|
if (initial_selection == NULL)
|
|
|
|
initial_selection = meta_display_get_tab_current (display,
|
|
|
|
type, screen,
|
|
|
|
screen->active_workspace);
|
|
|
|
|
|
|
|
meta_topic (META_DEBUG_KEYBINDINGS,
|
|
|
|
"Initially selecting window %s\n",
|
|
|
|
initial_selection ? initial_selection->desc : "(none)");
|
|
|
|
|
2002-10-18 18:19:05 -04:00
|
|
|
if (initial_selection != NULL)
|
|
|
|
{
|
|
|
|
if (binding->mask == 0)
|
|
|
|
{
|
|
|
|
/* If no modifiers, we can't do the "hold down modifier to keep
|
|
|
|
* moving" thing, so we just instaswitch by one window.
|
|
|
|
*/
|
|
|
|
meta_topic (META_DEBUG_FOCUS, "Activating %s due to switch/cycle windows with no modifiers\n",
|
|
|
|
initial_selection->desc);
|
|
|
|
meta_window_activate (initial_selection, event->xkey.time);
|
|
|
|
}
|
|
|
|
else if (meta_display_begin_grab_op (display,
|
|
|
|
screen,
|
|
|
|
NULL,
|
|
|
|
show_popup ?
|
|
|
|
tab_op_from_tab_type (type) :
|
|
|
|
cycle_op_from_tab_type (type),
|
|
|
|
FALSE,
|
|
|
|
0,
|
|
|
|
binding->mask,
|
|
|
|
event->xkey.time,
|
|
|
|
0, 0))
|
|
|
|
{
|
|
|
|
meta_ui_tab_popup_select (screen->tab_popup,
|
|
|
|
(MetaTabEntryKey) initial_selection->xwindow);
|
|
|
|
|
|
|
|
if (show_popup)
|
|
|
|
meta_ui_tab_popup_set_showing (screen->tab_popup,
|
|
|
|
TRUE);
|
|
|
|
else
|
|
|
|
meta_window_raise (initial_selection);
|
|
|
|
}
|
2001-06-23 23:41:44 -04:00
|
|
|
}
|
2001-06-23 22:22:10 -04:00
|
|
|
}
|
2001-06-23 23:18:10 -04:00
|
|
|
|
2002-07-06 12:50:48 -04:00
|
|
|
static void
|
|
|
|
handle_tab_forward (MetaDisplay *display,
|
2002-10-16 16:12:24 -04:00
|
|
|
MetaScreen *screen,
|
2002-07-06 12:50:48 -04:00
|
|
|
MetaWindow *event_window,
|
|
|
|
XEvent *event,
|
|
|
|
MetaKeyBinding *binding)
|
2001-06-23 23:18:10 -04:00
|
|
|
{
|
2002-10-16 16:12:24 -04:00
|
|
|
do_choose_window (display, screen,
|
2002-10-18 18:19:05 -04:00
|
|
|
event_window, event, binding, FALSE, TRUE);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
handle_tab_backward (MetaDisplay *display,
|
|
|
|
MetaScreen *screen,
|
|
|
|
MetaWindow *event_window,
|
|
|
|
XEvent *event,
|
|
|
|
MetaKeyBinding *binding)
|
|
|
|
{
|
|
|
|
do_choose_window (display, screen,
|
|
|
|
event_window, event, binding, TRUE, TRUE);
|
2002-06-08 23:44:16 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2002-07-06 12:50:48 -04:00
|
|
|
handle_cycle_forward (MetaDisplay *display,
|
2002-10-16 16:12:24 -04:00
|
|
|
MetaScreen *screen,
|
2002-07-06 12:50:48 -04:00
|
|
|
MetaWindow *event_window,
|
|
|
|
XEvent *event,
|
|
|
|
MetaKeyBinding *binding)
|
2002-06-08 23:44:16 -04:00
|
|
|
{
|
2002-10-16 16:12:24 -04:00
|
|
|
do_choose_window (display, screen,
|
2002-10-18 18:19:05 -04:00
|
|
|
event_window, event, binding, FALSE, FALSE);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
handle_cycle_backward (MetaDisplay *display,
|
|
|
|
MetaScreen *screen,
|
|
|
|
MetaWindow *event_window,
|
|
|
|
XEvent *event,
|
|
|
|
MetaKeyBinding *binding)
|
|
|
|
{
|
|
|
|
do_choose_window (display, screen,
|
|
|
|
event_window, event, binding, TRUE, FALSE);
|
2001-06-23 23:18:10 -04:00
|
|
|
}
|
2002-01-10 22:31:14 -05:00
|
|
|
|
2002-04-05 10:52:49 -05:00
|
|
|
static void
|
2002-04-28 00:52:26 -04:00
|
|
|
handle_toggle_fullscreen (MetaDisplay *display,
|
2002-10-16 16:12:24 -04:00
|
|
|
MetaScreen *screen,
|
2002-04-28 00:52:26 -04:00
|
|
|
MetaWindow *window,
|
|
|
|
XEvent *event,
|
|
|
|
MetaKeyBinding *binding)
|
2002-04-05 10:52:49 -05:00
|
|
|
{
|
|
|
|
if (window)
|
|
|
|
{
|
|
|
|
if (window->fullscreen)
|
|
|
|
meta_window_unmake_fullscreen (window);
|
2002-08-15 01:14:49 -04:00
|
|
|
else if (window->has_fullscreen_func)
|
2002-04-05 10:52:49 -05:00
|
|
|
meta_window_make_fullscreen (window);
|
|
|
|
}
|
|
|
|
}
|
2002-01-10 22:31:14 -05:00
|
|
|
|
|
|
|
static void
|
2002-04-28 00:52:26 -04:00
|
|
|
handle_toggle_maximize (MetaDisplay *display,
|
2002-10-16 16:12:24 -04:00
|
|
|
MetaScreen *screen,
|
2002-04-28 00:52:26 -04:00
|
|
|
MetaWindow *window,
|
|
|
|
XEvent *event,
|
|
|
|
MetaKeyBinding *binding)
|
|
|
|
{
|
|
|
|
if (window)
|
|
|
|
{
|
|
|
|
if (window->maximized)
|
|
|
|
meta_window_unmaximize (window);
|
2002-08-09 10:22:00 -04:00
|
|
|
else if (window->has_maximize_func)
|
2002-04-28 00:52:26 -04:00
|
|
|
meta_window_maximize (window);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2002-08-21 02:47:16 -04:00
|
|
|
static void
|
|
|
|
handle_maximize (MetaDisplay *display,
|
2002-10-16 16:12:24 -04:00
|
|
|
MetaScreen *screen,
|
2002-08-21 02:47:16 -04:00
|
|
|
MetaWindow *window,
|
|
|
|
XEvent *event,
|
|
|
|
MetaKeyBinding *binding)
|
|
|
|
{
|
|
|
|
if (window)
|
|
|
|
{
|
|
|
|
if (window->has_maximize_func)
|
|
|
|
meta_window_maximize (window);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
handle_unmaximize (MetaDisplay *display,
|
2002-10-16 16:12:24 -04:00
|
|
|
MetaScreen *screen,
|
2002-08-21 02:47:16 -04:00
|
|
|
MetaWindow *window,
|
|
|
|
XEvent *event,
|
|
|
|
MetaKeyBinding *binding)
|
|
|
|
{
|
|
|
|
if (window)
|
|
|
|
{
|
|
|
|
if (window->maximized)
|
|
|
|
meta_window_unmaximize (window);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2002-04-28 00:52:26 -04:00
|
|
|
static void
|
|
|
|
handle_toggle_shade (MetaDisplay *display,
|
2002-10-16 16:12:24 -04:00
|
|
|
MetaScreen *screen,
|
2002-04-28 00:52:26 -04:00
|
|
|
MetaWindow *window,
|
|
|
|
XEvent *event,
|
|
|
|
MetaKeyBinding *binding)
|
|
|
|
{
|
|
|
|
if (window)
|
|
|
|
{
|
|
|
|
if (window->shaded)
|
|
|
|
meta_window_unshade (window);
|
2002-08-09 10:22:00 -04:00
|
|
|
else if (window->has_shade_func)
|
2002-04-28 00:52:26 -04:00
|
|
|
meta_window_shade (window);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
handle_close_window (MetaDisplay *display,
|
2002-10-16 16:12:24 -04:00
|
|
|
MetaScreen *screen,
|
2002-04-28 00:52:26 -04:00
|
|
|
MetaWindow *window,
|
|
|
|
XEvent *event,
|
|
|
|
MetaKeyBinding *binding)
|
|
|
|
{
|
|
|
|
if (window)
|
2002-06-10 06:17:54 -04:00
|
|
|
if (window->has_close_func)
|
|
|
|
meta_window_delete (window, event->xkey.time);
|
2002-04-28 00:52:26 -04:00
|
|
|
}
|
|
|
|
|
2002-05-24 22:30:00 -04:00
|
|
|
static void
|
|
|
|
handle_minimize_window (MetaDisplay *display,
|
2002-10-16 16:12:24 -04:00
|
|
|
MetaScreen *screen,
|
2002-05-24 22:30:00 -04:00
|
|
|
MetaWindow *window,
|
|
|
|
XEvent *event,
|
|
|
|
MetaKeyBinding *binding)
|
|
|
|
{
|
|
|
|
if (window)
|
2002-06-10 06:17:54 -04:00
|
|
|
if (window->has_minimize_func)
|
|
|
|
meta_window_minimize (window);
|
2002-05-24 22:30:00 -04:00
|
|
|
}
|
|
|
|
|
2002-04-28 00:52:26 -04:00
|
|
|
static void
|
|
|
|
handle_begin_move (MetaDisplay *display,
|
2002-10-16 16:12:24 -04:00
|
|
|
MetaScreen *screen,
|
2002-04-28 00:52:26 -04:00
|
|
|
MetaWindow *window,
|
|
|
|
XEvent *event,
|
|
|
|
MetaKeyBinding *binding)
|
|
|
|
{
|
|
|
|
if (window)
|
|
|
|
{
|
Patch to provide extra cues to the user when using window menu move and
2002-08-08 Craig Black <blackc@speakeasy.net>
Patch to provide extra cues to the user when using
window menu move and resize, #85724.
* src/common.h: add new cursors
* src/display.c: (grab_op_is_mouse)
(meta_display_create_x_cursor), (xcursor_for_op),
(meta_display_set_grab_op_cursor),
(meta_display_begin_grab_op):
The keyboard move and resize grab ops now also use the mouse.
Allow the grab cursor to be changed during the grab op.
Hold onto the initial grab position in case of reset.
* src/display.h: save the initial grab position
* src/keybindings.c: (process_keyboard_move_grab),
(process_keyboard_resize_grab), (handle_begin_move),
(handle_begin_resize):
The keyboard move and resize grab ops now also use the mouse.
* src/window.c: (meta_window_client_message), (menu_callback),
(update_move), (update_resize),
(meta_window_handle_mouse_grab_op_event), (warp_pointer),
(meta_window_warp_pointer), (meta_window_begin_grab_op),
(meta_window_update_resize_grab_op):
When moving or resizing a window use the last grab position
in computing change increment.
Provide support for warping the mouse pointer.
* src/window.h: new warp pointer and grab op helper functions
2002-08-09 00:27:23 -04:00
|
|
|
meta_window_begin_grab_op (window,
|
|
|
|
META_GRAB_OP_KEYBOARD_MOVING,
|
|
|
|
event->xkey.time);
|
2002-04-28 00:52:26 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
handle_begin_resize (MetaDisplay *display,
|
2002-10-16 16:12:24 -04:00
|
|
|
MetaScreen *screen,
|
2002-04-28 00:52:26 -04:00
|
|
|
MetaWindow *window,
|
|
|
|
XEvent *event,
|
|
|
|
MetaKeyBinding *binding)
|
|
|
|
{
|
2002-07-09 23:51:01 -04:00
|
|
|
if (window)
|
|
|
|
{
|
Patch to provide extra cues to the user when using window menu move and
2002-08-08 Craig Black <blackc@speakeasy.net>
Patch to provide extra cues to the user when using
window menu move and resize, #85724.
* src/common.h: add new cursors
* src/display.c: (grab_op_is_mouse)
(meta_display_create_x_cursor), (xcursor_for_op),
(meta_display_set_grab_op_cursor),
(meta_display_begin_grab_op):
The keyboard move and resize grab ops now also use the mouse.
Allow the grab cursor to be changed during the grab op.
Hold onto the initial grab position in case of reset.
* src/display.h: save the initial grab position
* src/keybindings.c: (process_keyboard_move_grab),
(process_keyboard_resize_grab), (handle_begin_move),
(handle_begin_resize):
The keyboard move and resize grab ops now also use the mouse.
* src/window.c: (meta_window_client_message), (menu_callback),
(update_move), (update_resize),
(meta_window_handle_mouse_grab_op_event), (warp_pointer),
(meta_window_warp_pointer), (meta_window_begin_grab_op),
(meta_window_update_resize_grab_op):
When moving or resizing a window use the last grab position
in computing change increment.
Provide support for warping the mouse pointer.
* src/window.h: new warp pointer and grab op helper functions
2002-08-09 00:27:23 -04:00
|
|
|
meta_window_begin_grab_op (window,
|
|
|
|
META_GRAB_OP_KEYBOARD_RESIZING_UNKNOWN,
|
|
|
|
event->xkey.time);
|
2002-07-09 23:51:01 -04:00
|
|
|
}
|
2002-04-28 00:52:26 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
handle_toggle_sticky (MetaDisplay *display,
|
2002-10-16 16:12:24 -04:00
|
|
|
MetaScreen *screen,
|
2002-04-28 00:52:26 -04:00
|
|
|
MetaWindow *window,
|
|
|
|
XEvent *event,
|
|
|
|
MetaKeyBinding *binding)
|
|
|
|
{
|
|
|
|
if (window)
|
|
|
|
{
|
|
|
|
if (window->on_all_workspaces)
|
|
|
|
meta_window_unstick (window);
|
|
|
|
else
|
|
|
|
meta_window_stick (window);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
handle_move_to_workspace (MetaDisplay *display,
|
2002-10-16 16:12:24 -04:00
|
|
|
MetaScreen *screen,
|
2002-04-28 00:52:26 -04:00
|
|
|
MetaWindow *window,
|
|
|
|
XEvent *event,
|
|
|
|
MetaKeyBinding *binding)
|
|
|
|
{
|
|
|
|
int which;
|
|
|
|
MetaWorkspace *workspace;
|
|
|
|
|
|
|
|
which = GPOINTER_TO_INT (binding->handler->data);
|
|
|
|
|
2002-05-26 11:54:38 -04:00
|
|
|
if (window == NULL || window->always_sticky)
|
|
|
|
return;
|
|
|
|
|
2002-04-28 00:52:26 -04:00
|
|
|
workspace = NULL;
|
|
|
|
if (which < 0)
|
2002-10-16 16:12:24 -04:00
|
|
|
{
|
2002-04-28 00:52:26 -04:00
|
|
|
workspace = meta_workspace_get_neighbor (screen->active_workspace,
|
|
|
|
which);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2002-10-16 16:12:24 -04:00
|
|
|
workspace = meta_screen_get_workspace_by_index (screen, which);
|
2002-04-28 00:52:26 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
if (workspace)
|
|
|
|
{
|
2002-05-24 22:33:55 -04:00
|
|
|
/* Activate second, so the window is never unmapped */
|
2002-04-28 00:52:26 -04:00
|
|
|
meta_window_change_workspace (window, workspace);
|
2002-05-24 22:33:55 -04:00
|
|
|
meta_workspace_activate (workspace);
|
2002-04-28 00:52:26 -04:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* We could offer to create it I suppose */
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2002-05-28 23:11:24 -04:00
|
|
|
static void
|
|
|
|
handle_raise_or_lower (MetaDisplay *display,
|
2002-10-16 16:12:24 -04:00
|
|
|
MetaScreen *screen,
|
2002-05-28 23:11:24 -04:00
|
|
|
MetaWindow *window,
|
|
|
|
XEvent *event,
|
|
|
|
MetaKeyBinding *binding)
|
|
|
|
{
|
|
|
|
/* Get window at pointer */
|
|
|
|
|
|
|
|
if (window)
|
|
|
|
{
|
|
|
|
MetaWindow *above = NULL;
|
|
|
|
|
|
|
|
/* Check if top */
|
|
|
|
if (meta_stack_get_top (window->screen->stack) == window)
|
|
|
|
{
|
|
|
|
meta_window_lower (window);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* else check if windows in same layer are intersecting it */
|
|
|
|
|
|
|
|
above = meta_stack_get_above (window->screen->stack, window, TRUE);
|
|
|
|
|
|
|
|
while (above)
|
|
|
|
{
|
|
|
|
MetaRectangle tmp, win_rect, above_rect;
|
|
|
|
|
2002-10-20 11:22:40 -04:00
|
|
|
if (above->mapped)
|
|
|
|
{
|
|
|
|
meta_window_get_outer_rect (window, &win_rect);
|
|
|
|
meta_window_get_outer_rect (above, &above_rect);
|
|
|
|
|
|
|
|
/* Check if obscured */
|
|
|
|
if (meta_rectangle_intersect (&win_rect, &above_rect, &tmp))
|
|
|
|
{
|
|
|
|
meta_window_raise (window);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
2002-05-28 23:11:24 -04:00
|
|
|
|
|
|
|
above = meta_stack_get_above (window->screen->stack, above, TRUE);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* window is not obscured */
|
|
|
|
meta_window_lower (window);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2002-08-15 01:14:49 -04:00
|
|
|
static void
|
|
|
|
handle_raise (MetaDisplay *display,
|
2002-10-16 16:12:24 -04:00
|
|
|
MetaScreen *screen,
|
2002-08-15 01:14:49 -04:00
|
|
|
MetaWindow *window,
|
|
|
|
XEvent *event,
|
|
|
|
MetaKeyBinding *binding)
|
|
|
|
{
|
|
|
|
if (window)
|
|
|
|
{
|
|
|
|
meta_window_raise (window);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
handle_lower (MetaDisplay *display,
|
2002-10-16 16:12:24 -04:00
|
|
|
MetaScreen *screen,
|
2002-08-15 01:14:49 -04:00
|
|
|
MetaWindow *window,
|
|
|
|
XEvent *event,
|
|
|
|
MetaKeyBinding *binding)
|
|
|
|
{
|
|
|
|
if (window)
|
|
|
|
{
|
|
|
|
meta_window_lower (window);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2002-06-08 23:44:16 -04:00
|
|
|
static void
|
2002-06-09 00:04:19 -04:00
|
|
|
handle_workspace_switch (MetaDisplay *display,
|
2002-10-16 16:12:24 -04:00
|
|
|
MetaScreen *screen,
|
2002-06-09 00:04:19 -04:00
|
|
|
MetaWindow *window,
|
|
|
|
XEvent *event,
|
|
|
|
MetaKeyBinding *binding)
|
2002-06-08 23:44:16 -04:00
|
|
|
{
|
|
|
|
int motion;
|
2002-09-09 14:16:25 -04:00
|
|
|
|
2002-06-08 23:44:16 -04:00
|
|
|
motion = GPOINTER_TO_INT (binding->handler->data);
|
|
|
|
|
2002-10-16 16:12:24 -04:00
|
|
|
g_assert (motion < 0);
|
2002-06-08 23:44:16 -04:00
|
|
|
|
2002-06-27 01:08:32 -04:00
|
|
|
meta_topic (META_DEBUG_KEYBINDINGS,
|
|
|
|
"Starting tab between workspaces, showing popup\n");
|
|
|
|
|
|
|
|
if (meta_display_begin_grab_op (display,
|
|
|
|
screen,
|
2002-07-02 01:03:28 -04:00
|
|
|
NULL,
|
2002-06-27 01:08:32 -04:00
|
|
|
META_GRAB_OP_KEYBOARD_WORKSPACE_SWITCHING,
|
|
|
|
FALSE,
|
|
|
|
0,
|
|
|
|
event->xkey.state & ~(display->ignored_modifier_mask),
|
|
|
|
event->xkey.time,
|
|
|
|
0, 0))
|
2002-06-08 23:44:16 -04:00
|
|
|
{
|
2002-06-27 01:08:32 -04:00
|
|
|
MetaWorkspace *next;
|
2002-09-09 14:16:25 -04:00
|
|
|
|
2002-07-02 01:03:28 -04:00
|
|
|
next = meta_workspace_get_neighbor (screen->active_workspace, motion);
|
2002-06-27 01:08:32 -04:00
|
|
|
g_assert (next);
|
2002-09-09 14:16:25 -04:00
|
|
|
|
|
|
|
|
|
|
|
meta_topic (META_DEBUG_KEYBINDINGS,
|
|
|
|
"Activating target workspace\n");
|
|
|
|
|
|
|
|
switch_to_workspace (display, next);
|
2002-06-30 23:20:29 -04:00
|
|
|
|
2002-07-02 01:03:28 -04:00
|
|
|
meta_ui_tab_popup_select (screen->tab_popup, (MetaTabEntryKey) next);
|
2002-06-30 23:20:29 -04:00
|
|
|
|
2002-07-06 12:50:48 -04:00
|
|
|
/* only after selecting proper space */
|
2002-07-02 01:03:28 -04:00
|
|
|
meta_ui_tab_popup_set_showing (screen->tab_popup, TRUE);
|
2002-06-08 23:44:16 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2002-04-28 00:52:26 -04:00
|
|
|
static void
|
|
|
|
handle_spew_mark (MetaDisplay *display,
|
2002-10-16 16:12:24 -04:00
|
|
|
MetaScreen *screen,
|
2002-04-28 00:52:26 -04:00
|
|
|
MetaWindow *window,
|
|
|
|
XEvent *event,
|
|
|
|
MetaKeyBinding *binding)
|
2002-01-10 22:31:14 -05:00
|
|
|
{
|
|
|
|
meta_verbose ("-- MARK MARK MARK MARK --\n");
|
|
|
|
}
|
|
|
|
|
2002-02-08 01:01:58 -05:00
|
|
|
void
|
|
|
|
meta_set_keybindings_disabled (gboolean setting)
|
|
|
|
{
|
2002-06-15 23:03:08 -04:00
|
|
|
all_bindings_disabled = setting;
|
|
|
|
meta_topic (META_DEBUG_KEYBINDINGS,
|
|
|
|
"Keybindings %s\n", all_bindings_disabled ? "disabled" : "enabled");
|
2002-02-08 01:01:58 -05:00
|
|
|
}
|