mirror of
https://github.com/brl/mutter.git
synced 2024-11-28 19:10:43 -05:00
...
This commit is contained in:
parent
8a2841a8ab
commit
71d3333d4d
28
src/common.h
28
src/common.h
@ -53,7 +53,9 @@ typedef enum
|
|||||||
META_MENU_OP_SHADE = 1 << 5,
|
META_MENU_OP_SHADE = 1 << 5,
|
||||||
META_MENU_OP_UNSTICK = 1 << 6,
|
META_MENU_OP_UNSTICK = 1 << 6,
|
||||||
META_MENU_OP_STICK = 1 << 7,
|
META_MENU_OP_STICK = 1 << 7,
|
||||||
META_MENU_OP_WORKSPACES = 1 << 8
|
META_MENU_OP_WORKSPACES = 1 << 8,
|
||||||
|
META_MENU_OP_MOVE = 1 << 9,
|
||||||
|
META_MENU_OP_RESIZE = 1 << 10
|
||||||
} MetaMenuOp;
|
} MetaMenuOp;
|
||||||
|
|
||||||
typedef struct _MetaWindowMenu MetaWindowMenu;
|
typedef struct _MetaWindowMenu MetaWindowMenu;
|
||||||
@ -65,4 +67,28 @@ typedef void (* MetaWindowMenuFunc) (MetaWindowMenu *menu,
|
|||||||
int workspace,
|
int workspace,
|
||||||
gpointer data);
|
gpointer data);
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
META_GRAB_OP_NONE,
|
||||||
|
META_GRAB_OP_MOVING,
|
||||||
|
META_GRAB_OP_RESIZING_SE,
|
||||||
|
META_GRAB_OP_RESIZING_S,
|
||||||
|
META_GRAB_OP_RESIZING_SW,
|
||||||
|
META_GRAB_OP_RESIZING_N,
|
||||||
|
META_GRAB_OP_RESIZING_NE,
|
||||||
|
META_GRAB_OP_RESIZING_NW,
|
||||||
|
META_GRAB_OP_RESIZING_W,
|
||||||
|
META_GRAB_OP_RESIZING_E,
|
||||||
|
META_GRAB_OP_KEYBOARD_MOVING,
|
||||||
|
META_GRAB_OP_KEYBOARD_RESIZING_UNKNOWN,
|
||||||
|
META_GRAB_OP_KEYBOARD_RESIZING_S,
|
||||||
|
META_GRAB_OP_KEYBOARD_RESIZING_N,
|
||||||
|
META_GRAB_OP_KEYBOARD_RESIZING_W,
|
||||||
|
META_GRAB_OP_KEYBOARD_RESIZING_E
|
||||||
|
} MetaGrabOp;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
17
src/core.c
17
src/core.c
@ -131,6 +131,23 @@ meta_core_user_raise (Display *xdisplay,
|
|||||||
meta_window_raise (window);
|
meta_window_raise (window);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
meta_core_user_focus (Display *xdisplay,
|
||||||
|
Window frame_xwindow,
|
||||||
|
Time timestamp)
|
||||||
|
{
|
||||||
|
MetaDisplay *display;
|
||||||
|
MetaWindow *window;
|
||||||
|
|
||||||
|
display = meta_display_for_x_display (xdisplay);
|
||||||
|
window = meta_display_lookup_x_window (display, frame_xwindow);
|
||||||
|
|
||||||
|
if (window == NULL || window->frame == NULL)
|
||||||
|
meta_bug ("No such frame window 0x%lx!\n", frame_xwindow);
|
||||||
|
|
||||||
|
meta_window_focus (window, timestamp);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
meta_core_get_position (Display *xdisplay,
|
meta_core_get_position (Display *xdisplay,
|
||||||
Window frame_xwindow,
|
Window frame_xwindow,
|
||||||
|
@ -53,6 +53,10 @@ void meta_core_user_resize (Display *xdisplay,
|
|||||||
void meta_core_user_raise (Display *xdisplay,
|
void meta_core_user_raise (Display *xdisplay,
|
||||||
Window frame_xwindow);
|
Window frame_xwindow);
|
||||||
|
|
||||||
|
void meta_core_user_focus (Display *xdisplay,
|
||||||
|
Window frame_xwindow,
|
||||||
|
Time timestamp);
|
||||||
|
|
||||||
/* get position of client, same coord space expected by move */
|
/* get position of client, same coord space expected by move */
|
||||||
void meta_core_get_position (Display *xdisplay,
|
void meta_core_get_position (Display *xdisplay,
|
||||||
Window frame_xwindow,
|
Window frame_xwindow,
|
||||||
|
158
src/display.c
158
src/display.c
@ -277,6 +277,9 @@ meta_display_open (const char *name)
|
|||||||
display->last_button_num = 0;
|
display->last_button_num = 0;
|
||||||
display->is_double_click = FALSE;
|
display->is_double_click = FALSE;
|
||||||
|
|
||||||
|
display->grab_op = META_GRAB_OP_NONE;
|
||||||
|
display->grab_window = NULL;
|
||||||
|
|
||||||
set_string_hint (display,
|
set_string_hint (display,
|
||||||
display->leader_window,
|
display->leader_window,
|
||||||
display->atom_net_wm_name,
|
display->atom_net_wm_name,
|
||||||
@ -558,6 +561,7 @@ event_callback (XEvent *event,
|
|||||||
MetaWindow *window;
|
MetaWindow *window;
|
||||||
MetaDisplay *display;
|
MetaDisplay *display;
|
||||||
Window modified;
|
Window modified;
|
||||||
|
gboolean frame_was_receiver;
|
||||||
|
|
||||||
display = data;
|
display = data;
|
||||||
|
|
||||||
@ -591,30 +595,34 @@ event_callback (XEvent *event,
|
|||||||
else
|
else
|
||||||
window = NULL;
|
window = NULL;
|
||||||
|
|
||||||
|
frame_was_receiver = FALSE;
|
||||||
if (window &&
|
if (window &&
|
||||||
window->frame &&
|
window->frame &&
|
||||||
modified == window->frame->xwindow)
|
modified == window->frame->xwindow)
|
||||||
{
|
frame_was_receiver = TRUE;
|
||||||
meta_frame_event (window->frame, event);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (event->type)
|
switch (event->type)
|
||||||
{
|
{
|
||||||
case KeyPress:
|
case KeyPress:
|
||||||
case KeyRelease:
|
case KeyRelease:
|
||||||
|
if (window)
|
||||||
meta_display_process_key_event (display, window, event);
|
meta_display_process_key_event (display, window, event);
|
||||||
break;
|
break;
|
||||||
case ButtonPress:
|
case ButtonPress:
|
||||||
|
if (display->grab_op != META_GRAB_OP_NONE)
|
||||||
|
{
|
||||||
|
meta_verbose ("Ending grab op %d on window %s due to button press\n",
|
||||||
|
display->grab_op,
|
||||||
|
display->grab_window->desc);
|
||||||
|
meta_display_end_grab_op (display,
|
||||||
|
event->xbutton.time);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case ButtonRelease:
|
case ButtonRelease:
|
||||||
break;
|
break;
|
||||||
case MotionNotify:
|
case MotionNotify:
|
||||||
break;
|
break;
|
||||||
case EnterNotify:
|
case EnterNotify:
|
||||||
/* We handle it here if an undecorated window
|
|
||||||
* is involved, otherwise we handle it in frame.c
|
|
||||||
*/
|
|
||||||
/* do this even if window->has_focus to avoid races */
|
/* do this even if window->has_focus to avoid races */
|
||||||
if (window)
|
if (window)
|
||||||
meta_window_focus (window, event->xcrossing.time);
|
meta_window_focus (window, event->xcrossing.time);
|
||||||
@ -640,10 +648,23 @@ event_callback (XEvent *event,
|
|||||||
break;
|
break;
|
||||||
case DestroyNotify:
|
case DestroyNotify:
|
||||||
if (window)
|
if (window)
|
||||||
|
{
|
||||||
|
if (frame_was_receiver)
|
||||||
|
{
|
||||||
|
meta_warning ("Unexpected destruction of frame 0x%lx, not sure if this should silently fail or be considered a bug\n",
|
||||||
|
window->frame->xwindow);
|
||||||
|
meta_error_trap_push (display);
|
||||||
|
meta_window_destroy_frame (window->frame->window);
|
||||||
|
meta_error_trap_pop (display);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
meta_window_free (window); /* Unmanage destroyed window */
|
meta_window_free (window); /* Unmanage destroyed window */
|
||||||
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case UnmapNotify:
|
case UnmapNotify:
|
||||||
if (window)
|
if (!frame_was_receiver && window)
|
||||||
{
|
{
|
||||||
if (window->unmaps_pending == 0)
|
if (window->unmaps_pending == 0)
|
||||||
{
|
{
|
||||||
@ -664,8 +685,12 @@ event_callback (XEvent *event,
|
|||||||
break;
|
break;
|
||||||
case MapRequest:
|
case MapRequest:
|
||||||
if (window == NULL)
|
if (window == NULL)
|
||||||
window = meta_window_new (display, event->xmaprequest.window, FALSE);
|
{
|
||||||
else if (window)
|
window = meta_window_new (display, event->xmaprequest.window,
|
||||||
|
FALSE);
|
||||||
|
}
|
||||||
|
/* if frame was receiver it's some malicious send event or something */
|
||||||
|
else if (!frame_was_receiver && window)
|
||||||
{
|
{
|
||||||
if (window->minimized)
|
if (window->minimized)
|
||||||
meta_window_unminimize (window);
|
meta_window_unminimize (window);
|
||||||
@ -704,6 +729,7 @@ event_callback (XEvent *event,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
if (!frame_was_receiver)
|
||||||
meta_window_configure_request (window, event);
|
meta_window_configure_request (window, event);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -716,7 +742,7 @@ event_callback (XEvent *event,
|
|||||||
case CirculateRequest:
|
case CirculateRequest:
|
||||||
break;
|
break;
|
||||||
case PropertyNotify:
|
case PropertyNotify:
|
||||||
if (window)
|
if (window && !frame_was_receiver)
|
||||||
meta_window_property_notify (window, event);
|
meta_window_property_notify (window, event);
|
||||||
break;
|
break;
|
||||||
case SelectionClear:
|
case SelectionClear:
|
||||||
@ -730,6 +756,7 @@ event_callback (XEvent *event,
|
|||||||
case ClientMessage:
|
case ClientMessage:
|
||||||
if (window)
|
if (window)
|
||||||
{
|
{
|
||||||
|
if (!frame_was_receiver)
|
||||||
meta_window_client_message (window, event);
|
meta_window_client_message (window, event);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -1180,3 +1207,112 @@ meta_display_get_workspace_by_screen_index (MetaDisplay *display,
|
|||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
meta_display_begin_grab_op (MetaDisplay *display,
|
||||||
|
MetaWindow *window,
|
||||||
|
MetaGrabOp op,
|
||||||
|
gboolean pointer_already_grabbed,
|
||||||
|
int button,
|
||||||
|
gulong modmask,
|
||||||
|
Cursor cursor,
|
||||||
|
Time timestamp,
|
||||||
|
int root_x,
|
||||||
|
int root_y)
|
||||||
|
{
|
||||||
|
Window grabwindow;
|
||||||
|
|
||||||
|
meta_verbose ("Doing grab op %d on window %s button %d pointer already grabbed: %d\n",
|
||||||
|
op, window->desc, button, pointer_already_grabbed);
|
||||||
|
|
||||||
|
grabwindow = window->frame ? window->frame->xwindow : window->xwindow;
|
||||||
|
|
||||||
|
if (display->grab_op != META_GRAB_OP_NONE)
|
||||||
|
{
|
||||||
|
meta_warning ("Attempt to perform window operation %d on window %s when operation %d on %s already in effect\n",
|
||||||
|
op, window->desc, display->grab_op, display->grab_window->desc);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pointer_already_grabbed)
|
||||||
|
{
|
||||||
|
display->grab_have_pointer = TRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
meta_error_trap_push (display);
|
||||||
|
if (XGrabPointer (display->xdisplay,
|
||||||
|
grabwindow,
|
||||||
|
False,
|
||||||
|
PointerMotionMask | PointerMotionHintMask |
|
||||||
|
ButtonPressMask | ButtonReleaseMask |
|
||||||
|
KeyPressMask | KeyReleaseMask,
|
||||||
|
GrabModeAsync, GrabModeAsync,
|
||||||
|
None,
|
||||||
|
cursor,
|
||||||
|
timestamp) == GrabSuccess)
|
||||||
|
display->grab_have_pointer = TRUE;
|
||||||
|
meta_error_trap_pop (display);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!display->grab_have_pointer)
|
||||||
|
{
|
||||||
|
meta_verbose ("XGrabPointer() failed\n");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (op)
|
||||||
|
{
|
||||||
|
case META_GRAB_OP_KEYBOARD_MOVING:
|
||||||
|
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:
|
||||||
|
if (meta_window_grab_all_keys (window))
|
||||||
|
display->grab_have_keyboard = TRUE;
|
||||||
|
|
||||||
|
if (!display->grab_have_keyboard)
|
||||||
|
{
|
||||||
|
meta_verbose ("XGrabKeyboard() failed\n");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
/* non-keyboard grab ops */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
display->grab_op = op;
|
||||||
|
display->grab_window = window;
|
||||||
|
display->grab_button = button;
|
||||||
|
display->grab_root_x = root_x;
|
||||||
|
display->grab_root_y = root_y;
|
||||||
|
|
||||||
|
meta_verbose ("Grab op %d on window %s successful\n",
|
||||||
|
display->grab_op, display->grab_window->desc);
|
||||||
|
|
||||||
|
g_assert (display->grab_window != NULL);
|
||||||
|
g_assert (display->grab_op != META_GRAB_OP_NONE);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
meta_display_end_grab_op (MetaDisplay *display,
|
||||||
|
Time timestamp)
|
||||||
|
{
|
||||||
|
if (display->grab_op == META_GRAB_OP_NONE)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (display->grab_have_pointer)
|
||||||
|
XUngrabPointer (display->xdisplay, timestamp);
|
||||||
|
|
||||||
|
if (display->grab_have_keyboard)
|
||||||
|
meta_window_ungrab_all_keys (display->grab_window);
|
||||||
|
|
||||||
|
display->grab_window = NULL;
|
||||||
|
display->grab_op = META_GRAB_OP_NONE;
|
||||||
|
}
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
#include <X11/Xlib.h>
|
#include <X11/Xlib.h>
|
||||||
#include "eventqueue.h"
|
#include "eventqueue.h"
|
||||||
|
#include "common.h"
|
||||||
|
|
||||||
/* this doesn't really belong here, oh well. */
|
/* this doesn't really belong here, oh well. */
|
||||||
typedef struct _MetaRectangle MetaRectangle;
|
typedef struct _MetaRectangle MetaRectangle;
|
||||||
@ -118,6 +119,16 @@ struct _MetaDisplay
|
|||||||
Window last_button_xwindow;
|
Window last_button_xwindow;
|
||||||
int last_button_num;
|
int last_button_num;
|
||||||
guint is_double_click : 1;
|
guint is_double_click : 1;
|
||||||
|
|
||||||
|
/* current window operation */
|
||||||
|
MetaGrabOp grab_op;
|
||||||
|
MetaWindow *grab_window;
|
||||||
|
int grab_button;
|
||||||
|
int grab_root_x;
|
||||||
|
int grab_root_y;
|
||||||
|
gulong grab_mask;
|
||||||
|
guint grab_have_pointer : 1;
|
||||||
|
guint grab_have_keyboard : 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
gboolean meta_display_open (const char *name);
|
gboolean meta_display_open (const char *name);
|
||||||
@ -151,5 +162,19 @@ MetaWorkspace* meta_display_get_workspace_by_index (MetaDisplay *displa
|
|||||||
MetaWorkspace* meta_display_get_workspace_by_screen_index (MetaDisplay *display,
|
MetaWorkspace* meta_display_get_workspace_by_screen_index (MetaDisplay *display,
|
||||||
MetaScreen *screen,
|
MetaScreen *screen,
|
||||||
int index);
|
int index);
|
||||||
|
gboolean meta_display_begin_grab_op (MetaDisplay *display,
|
||||||
|
MetaWindow *window,
|
||||||
|
MetaGrabOp op,
|
||||||
|
gboolean pointer_already_grabbed,
|
||||||
|
int button,
|
||||||
|
gulong modmask,
|
||||||
|
Cursor cursor,
|
||||||
|
Time timestamp,
|
||||||
|
int root_x,
|
||||||
|
int root_y);
|
||||||
|
void meta_display_end_grab_op (MetaDisplay *display,
|
||||||
|
Time timestamp);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
97
src/frame.c
97
src/frame.c
@ -284,100 +284,3 @@ meta_frame_queue_draw (MetaFrame *frame)
|
|||||||
meta_ui_queue_frame_draw (frame->window->screen->ui,
|
meta_ui_queue_frame_draw (frame->window->screen->ui,
|
||||||
frame->xwindow);
|
frame->xwindow);
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean
|
|
||||||
meta_frame_event (MetaFrame *frame,
|
|
||||||
XEvent *event)
|
|
||||||
{
|
|
||||||
switch (event->type)
|
|
||||||
{
|
|
||||||
case KeyPress:
|
|
||||||
case KeyRelease:
|
|
||||||
meta_display_process_key_event (frame->window->display,
|
|
||||||
frame->window, event);
|
|
||||||
break;
|
|
||||||
case ButtonPress:
|
|
||||||
break;
|
|
||||||
case ButtonRelease:
|
|
||||||
break;
|
|
||||||
case MotionNotify:
|
|
||||||
break;
|
|
||||||
case EnterNotify:
|
|
||||||
/* We handle it here if a decorated window
|
|
||||||
* is involved, otherwise we handle it in display.c
|
|
||||||
*/
|
|
||||||
/* do this even if window->has_focus to avoid races */
|
|
||||||
meta_window_focus (frame->window,
|
|
||||||
event->xcrossing.time);
|
|
||||||
break;
|
|
||||||
case LeaveNotify:
|
|
||||||
break;
|
|
||||||
case FocusIn:
|
|
||||||
case FocusOut:
|
|
||||||
meta_window_notify_focus (frame->window,
|
|
||||||
event);
|
|
||||||
break;
|
|
||||||
case KeymapNotify:
|
|
||||||
break;
|
|
||||||
case Expose:
|
|
||||||
break;
|
|
||||||
case GraphicsExpose:
|
|
||||||
break;
|
|
||||||
case NoExpose:
|
|
||||||
break;
|
|
||||||
case VisibilityNotify:
|
|
||||||
break;
|
|
||||||
case CreateNotify:
|
|
||||||
break;
|
|
||||||
case DestroyNotify:
|
|
||||||
{
|
|
||||||
MetaDisplay *display;
|
|
||||||
|
|
||||||
meta_warning ("Unexpected destruction of frame 0x%lx, not sure if this should silently fail or be considered a bug\n", frame->xwindow);
|
|
||||||
display = frame->window->display;
|
|
||||||
meta_error_trap_push (display);
|
|
||||||
meta_window_destroy_frame (frame->window);
|
|
||||||
meta_error_trap_pop (display);
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case UnmapNotify:
|
|
||||||
break;
|
|
||||||
case MapNotify:
|
|
||||||
break;
|
|
||||||
case MapRequest:
|
|
||||||
break;
|
|
||||||
case ReparentNotify:
|
|
||||||
break;
|
|
||||||
case ConfigureNotify:
|
|
||||||
break;
|
|
||||||
case ConfigureRequest:
|
|
||||||
break;
|
|
||||||
case GravityNotify:
|
|
||||||
break;
|
|
||||||
case ResizeRequest:
|
|
||||||
break;
|
|
||||||
case CirculateNotify:
|
|
||||||
break;
|
|
||||||
case CirculateRequest:
|
|
||||||
break;
|
|
||||||
case PropertyNotify:
|
|
||||||
break;
|
|
||||||
case SelectionClear:
|
|
||||||
break;
|
|
||||||
case SelectionRequest:
|
|
||||||
break;
|
|
||||||
case SelectionNotify:
|
|
||||||
break;
|
|
||||||
case ColormapNotify:
|
|
||||||
break;
|
|
||||||
case ClientMessage:
|
|
||||||
break;
|
|
||||||
case MappingNotify:
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
@ -60,8 +60,6 @@ struct _MetaFrame
|
|||||||
void meta_window_ensure_frame (MetaWindow *window);
|
void meta_window_ensure_frame (MetaWindow *window);
|
||||||
void meta_window_destroy_frame (MetaWindow *window);
|
void meta_window_destroy_frame (MetaWindow *window);
|
||||||
void meta_frame_queue_draw (MetaFrame *frame);
|
void meta_frame_queue_draw (MetaFrame *frame);
|
||||||
gboolean meta_frame_event (MetaFrame *frame,
|
|
||||||
XEvent *event);
|
|
||||||
|
|
||||||
MetaFrameFlags meta_frame_get_flags (MetaFrame *frame);
|
MetaFrameFlags meta_frame_get_flags (MetaFrame *frame);
|
||||||
|
|
||||||
|
@ -1358,7 +1358,11 @@ meta_frames_button_press_event (GtkWidget *widget,
|
|||||||
return FALSE; /* already up to something */
|
return FALSE; /* already up to something */
|
||||||
|
|
||||||
if (event->button == 1)
|
if (event->button == 1)
|
||||||
|
{
|
||||||
meta_core_user_raise (gdk_display, frame->xwindow);
|
meta_core_user_raise (gdk_display, frame->xwindow);
|
||||||
|
meta_core_user_focus (gdk_display, frame->xwindow,
|
||||||
|
event->time);
|
||||||
|
}
|
||||||
|
|
||||||
if (event->button == 1 &&
|
if (event->button == 1 &&
|
||||||
(control == META_FRAME_CONTROL_MAXIMIZE ||
|
(control == META_FRAME_CONTROL_MAXIMIZE ||
|
||||||
|
@ -196,6 +196,9 @@ meta_screen_ungrab_keys (MetaScreen *screen)
|
|||||||
void
|
void
|
||||||
meta_window_grab_keys (MetaWindow *window)
|
meta_window_grab_keys (MetaWindow *window)
|
||||||
{
|
{
|
||||||
|
if (window->all_keys_grabbed)
|
||||||
|
return;
|
||||||
|
|
||||||
if (window->keys_grabbed)
|
if (window->keys_grabbed)
|
||||||
{
|
{
|
||||||
if (window->frame && !window->grab_on_frame)
|
if (window->frame && !window->grab_on_frame)
|
||||||
@ -235,17 +238,108 @@ meta_window_ungrab_keys (MetaWindow *window)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
meta_window_grab_all_keys (MetaWindow *window)
|
||||||
|
{
|
||||||
|
int result;
|
||||||
|
Window grabwindow;
|
||||||
|
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
meta_window_focus (window, CurrentTime);
|
||||||
|
|
||||||
|
grabwindow = window->frame ? window->frame->xwindow : window->xwindow;
|
||||||
|
|
||||||
|
meta_error_trap_push (window->display);
|
||||||
|
XGrabKey (window->display->xdisplay, AnyKey, AnyModifier,
|
||||||
|
grabwindow, True,
|
||||||
|
GrabModeAsync, GrabModeAsync);
|
||||||
|
|
||||||
|
result = meta_error_trap_pop (window->display);
|
||||||
|
if (result != Success)
|
||||||
|
{
|
||||||
|
meta_verbose ("Global key grab failed for window %s\n", window->desc);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
window->keys_grabbed = FALSE;
|
||||||
|
window->all_keys_grabbed = TRUE;
|
||||||
|
window->grab_on_frame = window->frame != NULL;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
meta_window_ungrab_all_keys (MetaWindow *window)
|
||||||
|
{
|
||||||
|
if (window->all_keys_grabbed)
|
||||||
|
{
|
||||||
|
Window grabwindow;
|
||||||
|
|
||||||
|
grabwindow = (window->frame && window->grab_on_frame) ?
|
||||||
|
window->frame->xwindow : window->xwindow;
|
||||||
|
|
||||||
|
meta_error_trap_push (window->display);
|
||||||
|
XUngrabKey (window->display->xdisplay,
|
||||||
|
AnyKey, AnyModifier,
|
||||||
|
grabwindow);
|
||||||
|
meta_error_trap_pop (window->display);
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
int map_size;
|
||||||
|
XModifierKeymap *mod_keymap;
|
||||||
|
gboolean retval = FALSE;
|
||||||
|
|
||||||
|
/* FIXME this is ass-slow, cache the modmap */
|
||||||
|
|
||||||
|
mod_keymap = XGetModifierMapping (display->xdisplay);
|
||||||
|
|
||||||
|
map_size = 8 * mod_keymap->max_keypermod;
|
||||||
|
i = 0;
|
||||||
|
while (i < map_size) {
|
||||||
|
|
||||||
|
if (keycode == mod_keymap->modifiermap[i]) {
|
||||||
|
retval = TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
|
||||||
|
XFreeModifiermap (mod_keymap);
|
||||||
|
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
process_event (MetaKeyBinding *bindings,
|
process_event (MetaKeyBinding *bindings,
|
||||||
MetaDisplay *display,
|
MetaDisplay *display,
|
||||||
MetaWindow *window,
|
MetaWindow *window,
|
||||||
XEvent *event)
|
XEvent *event,
|
||||||
|
KeySym keysym)
|
||||||
{
|
{
|
||||||
KeySym keysym;
|
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
keysym = XKeycodeToKeysym (display->xdisplay, event->xkey.keycode, 0);
|
|
||||||
|
|
||||||
i = 0;
|
i = 0;
|
||||||
while (bindings[i].keysym != None)
|
while (bindings[i].keysym != None)
|
||||||
{
|
{
|
||||||
@ -267,8 +361,102 @@ meta_display_process_key_event (MetaDisplay *display,
|
|||||||
MetaWindow *window,
|
MetaWindow *window,
|
||||||
XEvent *event)
|
XEvent *event)
|
||||||
{
|
{
|
||||||
process_event (screen_bindings, display, window, event);
|
KeySym keysym;
|
||||||
process_event (window_bindings, display, window, event);
|
gboolean handled;
|
||||||
|
|
||||||
|
g_return_if_fail (window != NULL);
|
||||||
|
|
||||||
|
keysym = XKeycodeToKeysym (display->xdisplay, event->xkey.keycode, 0);
|
||||||
|
|
||||||
|
meta_verbose ("Processing key %s event, keysym: %s state: 0x%x window: %s\n",
|
||||||
|
event->type == KeyPress ? "press" : "release",
|
||||||
|
XKeysymToString (keysym), event->xkey.state,
|
||||||
|
window->desc);
|
||||||
|
|
||||||
|
if (!window->all_keys_grabbed)
|
||||||
|
{
|
||||||
|
/* Do the normal keybindings */
|
||||||
|
process_event (screen_bindings, display, window, event, keysym);
|
||||||
|
process_event (window_bindings, display, window, event, keysym);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If we get here we have a global grab, because
|
||||||
|
* we're in some special keyboard mode such as window move
|
||||||
|
* mode.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (display->grab_op == META_GRAB_OP_NONE)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* don't end grabs on modifier key presses */
|
||||||
|
if (is_modifier (display, event->xkey.keycode))
|
||||||
|
return;
|
||||||
|
|
||||||
|
handled = FALSE;
|
||||||
|
|
||||||
|
if (display->grab_op == META_GRAB_OP_KEYBOARD_MOVING &&
|
||||||
|
display->grab_window == window)
|
||||||
|
{
|
||||||
|
int x, y;
|
||||||
|
int incr;
|
||||||
|
gboolean smart_snap;
|
||||||
|
|
||||||
|
if (window == NULL)
|
||||||
|
meta_bug ("NULL window while META_GRAB_OP_MOVING\n");
|
||||||
|
|
||||||
|
meta_window_get_position (window, &x, &y);
|
||||||
|
|
||||||
|
smart_snap =
|
||||||
|
(event->xkey.state & ControlMask) != 0 &&
|
||||||
|
(event->xkey.state & ShiftMask) != 0;
|
||||||
|
|
||||||
|
/* FIXME replace LARGE_INCREMENT with intelligent snapping */
|
||||||
|
#define SMALL_INCREMENT 1
|
||||||
|
#define NORMAL_INCREMENT 10
|
||||||
|
#define LARGE_INCREMENT 100
|
||||||
|
|
||||||
|
if (smart_snap)
|
||||||
|
incr = LARGE_INCREMENT;
|
||||||
|
else if (event->xkey.state & ControlMask)
|
||||||
|
incr = SMALL_INCREMENT;
|
||||||
|
else
|
||||||
|
incr = NORMAL_INCREMENT;
|
||||||
|
|
||||||
|
switch (keysym)
|
||||||
|
{
|
||||||
|
case XK_Up:
|
||||||
|
y -= incr;
|
||||||
|
handled = TRUE;
|
||||||
|
break;
|
||||||
|
case XK_Down:
|
||||||
|
y += incr;
|
||||||
|
handled = TRUE;
|
||||||
|
break;
|
||||||
|
case XK_Left:
|
||||||
|
x -= incr;
|
||||||
|
handled = TRUE;
|
||||||
|
break;
|
||||||
|
case XK_Right:
|
||||||
|
x += incr;
|
||||||
|
handled = TRUE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (handled)
|
||||||
|
meta_window_move (window, x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* end grab if a key that isn't used gets pressed */
|
||||||
|
if (!handled)
|
||||||
|
{
|
||||||
|
meta_verbose ("Ending grab op %d on key press event sym %s\n",
|
||||||
|
display->grab_op, XKeysymToString (keysym));
|
||||||
|
meta_display_end_grab_op (display, event->xkey.time);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -30,6 +30,8 @@ void meta_screen_grab_keys (MetaScreen *screen);
|
|||||||
void meta_screen_ungrab_keys (MetaScreen *screen);
|
void meta_screen_ungrab_keys (MetaScreen *screen);
|
||||||
void meta_window_grab_keys (MetaWindow *window);
|
void meta_window_grab_keys (MetaWindow *window);
|
||||||
void meta_window_ungrab_keys (MetaWindow *window);
|
void meta_window_ungrab_keys (MetaWindow *window);
|
||||||
|
gboolean meta_window_grab_all_keys (MetaWindow *window);
|
||||||
|
void meta_window_ungrab_all_keys (MetaWindow *window);
|
||||||
void meta_display_process_key_event (MetaDisplay *display,
|
void meta_display_process_key_event (MetaDisplay *display,
|
||||||
MetaWindow *window,
|
MetaWindow *window,
|
||||||
XEvent *event);
|
XEvent *event);
|
||||||
|
@ -50,6 +50,8 @@ static MenuItem menuitems[] = {
|
|||||||
{ META_MENU_OP_UNMAXIMIZE, NULL, N_("_Unmaximize") },
|
{ META_MENU_OP_UNMAXIMIZE, NULL, N_("_Unmaximize") },
|
||||||
{ META_MENU_OP_SHADE, NULL, N_("_Shade") },
|
{ META_MENU_OP_SHADE, NULL, N_("_Shade") },
|
||||||
{ META_MENU_OP_UNSHADE, NULL, N_("U_nshade") },
|
{ META_MENU_OP_UNSHADE, NULL, N_("U_nshade") },
|
||||||
|
{ META_MENU_OP_MOVE, NULL, N_("Mo_ve") },
|
||||||
|
{ META_MENU_OP_RESIZE, NULL, N_("_Resize") },
|
||||||
{ 0, NULL, NULL }, /* separator */
|
{ 0, NULL, NULL }, /* separator */
|
||||||
{ META_MENU_OP_STICK, NULL, N_("Put on _All Workspaces") },
|
{ META_MENU_OP_STICK, NULL, N_("Put on _All Workspaces") },
|
||||||
{ META_MENU_OP_UNSTICK, NULL, N_("Only on _This Workspace") }
|
{ META_MENU_OP_UNSTICK, NULL, N_("Only on _This Workspace") }
|
||||||
|
33
src/window.c
33
src/window.c
@ -251,6 +251,7 @@ meta_window_new (MetaDisplay *display, Window xwindow,
|
|||||||
window->calc_showing_queued = FALSE;
|
window->calc_showing_queued = FALSE;
|
||||||
window->keys_grabbed = FALSE;
|
window->keys_grabbed = FALSE;
|
||||||
window->grab_on_frame = FALSE;
|
window->grab_on_frame = FALSE;
|
||||||
|
window->all_keys_grabbed = FALSE;
|
||||||
window->withdrawn = FALSE;
|
window->withdrawn = FALSE;
|
||||||
window->initial_workspace_set = FALSE;
|
window->initial_workspace_set = FALSE;
|
||||||
window->calc_placement = FALSE;
|
window->calc_placement = FALSE;
|
||||||
@ -468,6 +469,9 @@ meta_window_free (MetaWindow *window)
|
|||||||
|
|
||||||
window->unmanaging = TRUE;
|
window->unmanaging = TRUE;
|
||||||
|
|
||||||
|
if (window->display->grab_window == window)
|
||||||
|
meta_display_end_grab_op (window->display, CurrentTime);
|
||||||
|
|
||||||
if (window->display->focus_window == window)
|
if (window->display->focus_window == window)
|
||||||
window->display->focus_window = NULL;
|
window->display->focus_window = NULL;
|
||||||
|
|
||||||
@ -1514,6 +1518,14 @@ meta_window_focus (MetaWindow *window,
|
|||||||
meta_verbose ("Setting input focus to window %s, input: %d take_focus: %d\n",
|
meta_verbose ("Setting input focus to window %s, input: %d take_focus: %d\n",
|
||||||
window->desc, window->input, window->take_focus);
|
window->desc, window->input, window->take_focus);
|
||||||
|
|
||||||
|
if (window->display->grab_window &&
|
||||||
|
window->display->grab_window->all_keys_grabbed)
|
||||||
|
{
|
||||||
|
meta_verbose ("Current focus window %s has global keygrab, not focusing window %s after all\n",
|
||||||
|
window->display->grab_window->desc, window->desc);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/* For output-only or shaded windows, focus the frame.
|
/* For output-only or shaded windows, focus the frame.
|
||||||
* This seems to result in the client window getting key events
|
* This seems to result in the client window getting key events
|
||||||
* though, so I don't know if it's icccm-compliant.
|
* though, so I don't know if it's icccm-compliant.
|
||||||
@ -3561,6 +3573,19 @@ menu_callback (MetaWindowMenu *menu,
|
|||||||
meta_window_unstick (window);
|
meta_window_unstick (window);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case META_MENU_OP_MOVE:
|
||||||
|
meta_window_raise (window);
|
||||||
|
meta_display_begin_grab_op (window->display,
|
||||||
|
window,
|
||||||
|
META_GRAB_OP_KEYBOARD_MOVING,
|
||||||
|
FALSE, 0, 0, None,
|
||||||
|
CurrentTime,
|
||||||
|
0, 0);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case META_MENU_OP_RESIZE:
|
||||||
|
break;
|
||||||
|
|
||||||
case 0:
|
case 0:
|
||||||
/* nothing */
|
/* nothing */
|
||||||
break;
|
break;
|
||||||
@ -3592,7 +3617,7 @@ meta_window_show_menu (MetaWindow *window,
|
|||||||
ops = 0;
|
ops = 0;
|
||||||
insensitive = 0;
|
insensitive = 0;
|
||||||
|
|
||||||
ops |= (META_MENU_OP_DELETE | META_MENU_OP_WORKSPACES | META_MENU_OP_MINIMIZE);
|
ops |= (META_MENU_OP_DELETE | META_MENU_OP_WORKSPACES | META_MENU_OP_MINIMIZE | META_MENU_OP_MOVE | META_MENU_OP_RESIZE);
|
||||||
|
|
||||||
if (window->maximized)
|
if (window->maximized)
|
||||||
ops |= META_MENU_OP_UNMAXIMIZE;
|
ops |= META_MENU_OP_UNMAXIMIZE;
|
||||||
@ -3621,6 +3646,12 @@ meta_window_show_menu (MetaWindow *window,
|
|||||||
if (!window->has_shade_func)
|
if (!window->has_shade_func)
|
||||||
insensitive |= META_MENU_OP_SHADE | META_MENU_OP_UNSHADE;
|
insensitive |= META_MENU_OP_SHADE | META_MENU_OP_UNSHADE;
|
||||||
|
|
||||||
|
if (!window->has_move_func)
|
||||||
|
insensitive |= META_MENU_OP_MOVE;
|
||||||
|
|
||||||
|
if (!window->has_resize_func)
|
||||||
|
insensitive |= META_MENU_OP_RESIZE;
|
||||||
|
|
||||||
menu =
|
menu =
|
||||||
meta_ui_window_menu_new (window->screen->ui,
|
meta_ui_window_menu_new (window->screen->ui,
|
||||||
window->xwindow,
|
window->xwindow,
|
||||||
|
@ -162,8 +162,9 @@ struct _MetaWindow
|
|||||||
guint calc_showing_queued : 1;
|
guint calc_showing_queued : 1;
|
||||||
|
|
||||||
/* Used by keybindings.c */
|
/* Used by keybindings.c */
|
||||||
guint keys_grabbed : 1;
|
guint keys_grabbed : 1; /* normal keybindings grabbed */
|
||||||
guint grab_on_frame : 1;
|
guint grab_on_frame : 1; /* grabs are on the frame */
|
||||||
|
guint all_keys_grabbed : 1; /* AnyKey grabbed */
|
||||||
|
|
||||||
/* Set if the reason for unmanaging the window is that
|
/* Set if the reason for unmanaging the window is that
|
||||||
* it was withdrawn
|
* it was withdrawn
|
||||||
|
Loading…
Reference in New Issue
Block a user