summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrhp <rhp>2001-07-26 03:14:45 +0000
committerrhp <rhp>2001-07-26 03:14:45 +0000
commitb6e4c8bc414cf8905e5b2d0f2f84c2155acd10cf (patch)
treef60350199153b15fdc884d2b5ceeed8a8dbb0619
parent46edcc4832cfb9e7882b2ff4c77e3b45ae9415d0 (diff)
downloadmetacity-b6e4c8bc414cf8905e5b2d0f2f84c2155acd10cf.tar.gz
metacity-b6e4c8bc414cf8905e5b2d0f2f84c2155acd10cf.tar.bz2
...
-rw-r--r--README53
-rw-r--r--src/common.h24
-rw-r--r--src/core.c101
-rw-r--r--src/core.h26
-rw-r--r--src/display.c288
-rw-r--r--src/display.h11
-rw-r--r--src/frames.c656
-rw-r--r--src/frames.h38
-rw-r--r--src/keybindings.c20
-rw-r--r--src/screen.c25
-rw-r--r--src/screen.h4
-rw-r--r--src/ui.c6
-rw-r--r--src/ui.h2
-rw-r--r--src/window.c4
-rw-r--r--src/window.h3
15 files changed, 646 insertions, 615 deletions
diff --git a/README b/README
index 6adaa43..1324bc6 100644
--- a/README
+++ b/README
@@ -31,8 +31,10 @@ METACITY FEATURES
letter in the menu item works.
Choose Move from menu, and arrow keys to move the window.
+
While moving, hold down Control to move slower, and
Shift to snap to edges.
+
Choose Resize from menu, and nothing happens yet, but
eventually I might implement something.
@@ -85,11 +87,17 @@ METACITY FEATURES
look in frames.c:meta_frames_class_init() for all the style
properties that you can configure.
+ Metacity-specific styles can also be included in any GTK+
+ theme.
+
- Metacity implements much of the new window manager spec from
freedesktop.org, and much of the ICCCM. But then there are
parts of each that it doesn't implement, just because I haven't
yet.
+ - Uses Pango to render text, so has cool i18n capabilities.
+ Supports UTF-8 window titles and such.
+
METACITY BUGS, NON-FEATURES, AND CAVEATS
===
@@ -154,6 +162,17 @@ METACITY BUGS, NON-FEATURES, AND CAVEATS
Metacity needs to keep this area up-to-date using the hints the
panel sets.
+ - Should really support click-to-focus as an option.
+
+ - Windows has a neat way of implementing Alt-Tab for
+ window cycling that I would like to copy. (The little
+ popup window thing.)
+
+ - Should Metacity support flipping in right-to-left locales?
+ I don't know what window managers look like in a right-to-left
+ locale. I assume the window titles should be right-justified;
+ should the window controls also be flipped?
+
COMPILING METACITY
===
@@ -161,22 +180,32 @@ You need GTK+ 1.3.x (to become 2.0). See configure.in for the exact
version you need. Metacity is a fairly trivial 6000-line C program, so
once you get GTK+ built it should be no problem to build Metacity.
-REPORTING BUGS
+REPORTING BUGS AND SUBMITTING PATCHES
===
Report new bugs to hp@redhat.com for now. Will switch to Bugzilla
sometime probably.
+Feel free to send patches too; Metacity is really small and simple, so
+if you find a bug or want to add a feature it should be pretty easy.
+
FAQ
===
Q: Will you add my feature?
-A: Probably not, unless it makes sense to turn on by unconditionally,
+A: If it makes sense to turn on unconditionally,
or is genuinely a harmless preference that I would not
- be embarrassed to put in a user-friendly configuration dialog.
+ be embarrassed to put in a simple, uncluttered, user-friendly
+ configuration dialog.
+
+ If the only rationale for your feature is that other window
+ managers have it, or that you are personally used to it, or something
+ like that, then I will not be impressed. Metacity is firmly in the
+ "choose good defaults" camp rather than the "offer 6 equally broken
+ ways to do it, and let the user pick one" camp.
- Metacity has a "no crackrock" policy, with some exceptions
+ This is part of a "no crackrock" policy, despite some exceptions
I'm mildly embarrassed about. For example, multiple workspaces
probably constitute crackrock, they confuse most users
and really are not that useful if you have a decent tasklist and
@@ -185,7 +214,11 @@ A: Probably not, unless it makes sense to turn on by unconditionally,
keybindings are definitely on crack.
But don't think unlimited crack is OK just because I slipped up a
- little. No slippery slope here.
+ little. No slippery slope here.
+
+ Don't let this discourage patches and fixes - I love those. ;-)
+ Just be prepared to hear the above objections if your patch
+ adds some crack-ridden configuration option.
Q: How do I add a configuration option?
@@ -196,10 +229,12 @@ Q: Will Metacity be part of GNOME?
A: If Metacity is ever better than the other options, and the GNOME
Project so chooses. But Metacity may continue to suck forever
- because I might get tired of it; or Metacity's conservative
- nature might not make sense for the snazzy world of
- GNOME. Who knows. I'm not worrying about this, and you shouldn't
- either.
+ because I might get tired of working on it; or Metacity's feature
+ set might not make sense for GNOME. Who knows. I'm not worrying
+ about this, and you shouldn't either.
+
+ For now Metacity is my toy hobby project that I work on when I feel
+ like it.
Q: Why can't I move XMMS?
diff --git a/src/common.h b/src/common.h
index af80705..87f830c 100644
--- a/src/common.h
+++ b/src/common.h
@@ -70,6 +70,7 @@ typedef void (* MetaWindowMenuFunc) (MetaWindowMenu *menu,
typedef enum
{
META_GRAB_OP_NONE,
+ /* Mouse ops */
META_GRAB_OP_MOVING,
META_GRAB_OP_RESIZING_SE,
META_GRAB_OP_RESIZING_S,
@@ -79,14 +80,35 @@ typedef enum
META_GRAB_OP_RESIZING_NW,
META_GRAB_OP_RESIZING_W,
META_GRAB_OP_RESIZING_E,
+ /* Keyboard ops */
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
+ META_GRAB_OP_KEYBOARD_RESIZING_E,
+ /* Frame button ops */
+ META_GRAB_OP_CLICKING_MINIMIZE,
+ META_GRAB_OP_CLICKING_MAXIMIZE,
+ META_GRAB_OP_CLICKING_DELETE,
+ META_GRAB_OP_CLICKING_MENU
} MetaGrabOp;
+
+typedef enum
+{
+ META_CURSOR_DEFAULT,
+ META_CURSOR_NORTH_RESIZE,
+ META_CURSOR_SOUTH_RESIZE,
+ META_CURSOR_WEST_RESIZE,
+ META_CURSOR_EAST_RESIZE,
+ META_CURSOR_SE_RESIZE,
+ META_CURSOR_SW_RESIZE,
+ META_CURSOR_NE_RESIZE,
+ META_CURSOR_NW_RESIZE
+
+} MetaCursor;
+
#endif
diff --git a/src/core.c b/src/core.c
index 07c5e98..9e70907 100644
--- a/src/core.c
+++ b/src/core.c
@@ -393,3 +393,104 @@ meta_core_show_window_menu (Display *xdisplay,
meta_window_show_menu (window, root_x, root_y, button, timestamp);
}
+gboolean
+meta_core_begin_grab_op (Display *xdisplay,
+ Window frame_xwindow,
+ MetaGrabOp op,
+ gboolean pointer_already_grabbed,
+ int button,
+ gulong modmask,
+ Time timestamp,
+ int root_x,
+ int root_y)
+{
+ 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);
+
+ return meta_display_begin_grab_op (display, window,
+ op, pointer_already_grabbed,
+ button, modmask,
+ timestamp, root_x, root_y);
+}
+
+void
+meta_core_end_grab_op (Display *xdisplay,
+ Time timestamp)
+{
+ MetaDisplay *display;
+
+ display = meta_display_for_x_display (xdisplay);
+
+ meta_display_end_grab_op (display, timestamp);
+}
+
+MetaGrabOp
+meta_core_get_grab_op (Display *xdisplay)
+{
+ MetaDisplay *display;
+
+ display = meta_display_for_x_display (xdisplay);
+
+ return display->grab_op;
+}
+
+Window
+meta_core_get_grab_frame (Display *xdisplay)
+{
+ MetaDisplay *display;
+
+ display = meta_display_for_x_display (xdisplay);
+
+ if (display->grab_op != META_GRAB_OP_NONE &&
+ display->grab_window->frame)
+ return display->grab_window->frame->xwindow;
+ else
+ return None;
+}
+
+int
+meta_core_get_grab_button (Display *xdisplay)
+{
+ MetaDisplay *display;
+
+ display = meta_display_for_x_display (xdisplay);
+
+ if (display->grab_op == META_GRAB_OP_NONE)
+ return -1;
+
+ return display->grab_button;
+}
+
+void
+meta_core_grab_buttons (Display *xdisplay,
+ Window frame_xwindow)
+{
+ MetaDisplay *display;
+
+ display = meta_display_for_x_display (xdisplay);
+
+ meta_display_grab_window_buttons (display, frame_xwindow);
+}
+
+void
+meta_core_set_screen_cursor (Display *xdisplay,
+ Window frame_on_screen,
+ MetaCursor cursor)
+{
+ MetaDisplay *display;
+ MetaWindow *window;
+
+ display = meta_display_for_x_display (xdisplay);
+ window = meta_display_lookup_x_window (display, frame_on_screen);
+
+ if (window == NULL || window->frame == NULL)
+ meta_bug ("No such frame window 0x%lx!\n", frame_on_screen);
+
+ meta_screen_set_cursor (window->screen, cursor);
+}
diff --git a/src/core.h b/src/core.h
index 75bd8f7..3b291ce 100644
--- a/src/core.h
+++ b/src/core.h
@@ -94,7 +94,6 @@ int meta_core_get_active_workspace (Screen *xscreen);
int meta_core_get_frame_workspace (Display *xdisplay,
Window frame_xwindow);
-
void meta_core_show_window_menu (Display *xdisplay,
Window frame_xwindow,
int root_x,
@@ -102,6 +101,31 @@ void meta_core_show_window_menu (Display *xdisplay,
int button,
Time timestamp);
+gboolean meta_core_begin_grab_op (Display *xdisplay,
+ Window frame_xwindow,
+ MetaGrabOp op,
+ gboolean pointer_already_grabbed,
+ int button,
+ gulong modmask,
+ Time timestamp,
+ int root_x,
+ int root_y);
+void meta_core_end_grab_op (Display *xdisplay,
+ Time timestamp);
+MetaGrabOp meta_core_get_grab_op (Display *xdisplay);
+Window meta_core_get_grab_frame (Display *xdisplay);
+int meta_core_get_grab_button (Display *xdisplay);
+
+
+void meta_core_grab_buttons (Display *xdisplay,
+ Window frame_xwindow);
+
+void meta_core_set_screen_cursor (Display *xdisplay,
+ Window frame_on_screen,
+ MetaCursor cursor);
+
#endif
+
+
diff --git a/src/display.c b/src/display.c
index aec65d7..0622701 100644
--- a/src/display.c
+++ b/src/display.c
@@ -29,6 +29,7 @@
#include "keybindings.h"
#include "workspace.h"
#include <X11/Xatom.h>
+#include <X11/cursorfont.h>
#include <string.h>
#define USE_GDK_DISPLAY
@@ -555,6 +556,47 @@ event_queue_callback (XEvent *event,
}
static gboolean
+grab_op_is_mouse (MetaGrabOp op)
+{
+ switch (op)
+ {
+ case META_GRAB_OP_MOVING:
+ case META_GRAB_OP_RESIZING_SE:
+ case META_GRAB_OP_RESIZING_S:
+ case META_GRAB_OP_RESIZING_SW:
+ case META_GRAB_OP_RESIZING_N:
+ case META_GRAB_OP_RESIZING_NE:
+ case META_GRAB_OP_RESIZING_NW:
+ case META_GRAB_OP_RESIZING_W:
+ case META_GRAB_OP_RESIZING_E:
+ return TRUE;
+ break;
+
+ default:
+ return FALSE;
+ }
+}
+
+static gboolean
+grab_op_is_keyboard (MetaGrabOp op)
+{
+ 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:
+ return TRUE;
+ break;
+
+ default:
+ return FALSE;
+ }
+}
+
+static gboolean
event_callback (XEvent *event,
gpointer data)
{
@@ -609,18 +651,48 @@ event_callback (XEvent *event,
meta_display_process_key_event (display, window, event);
break;
case ButtonPress:
- if (display->grab_op != META_GRAB_OP_NONE)
+ if ((grab_op_is_mouse (display->grab_op) &&
+ display->grab_button != event->xbutton.button &&
+ display->grab_window == window) ||
+ grab_op_is_keyboard (display->grab_op))
{
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);
+ }
+ else if (window)
+ {
+ if (event->xbutton.button == 1)
+ {
+ meta_window_raise (window);
+ meta_window_focus (window, event->xbutton.time);
+ }
+ else if (event->xbutton.button == 2)
+ {
+ /* FIXME begin move */
+
+ }
+ else if (event->xbutton.button == 3)
+ {
+ meta_window_show_menu (window,
+ event->xbutton.x_root,
+ event->xbutton.y_root,
+ event->xbutton.button,
+ event->xbutton.time);
+ }
}
break;
case ButtonRelease:
+ if (grab_op_is_mouse (display->grab_op) &&
+ display->grab_window == window)
+ meta_window_handle_mouse_grab_op_event (window, event);
break;
case MotionNotify:
+ if (grab_op_is_mouse (display->grab_op) &&
+ display->grab_window == window)
+ meta_window_handle_mouse_grab_op_event (window, event);
break;
case EnterNotify:
/* do this even if window->has_focus to avoid races */
@@ -649,6 +721,10 @@ event_callback (XEvent *event,
case DestroyNotify:
if (window)
{
+ if (display->grab_op != META_GRAB_OP_NONE &&
+ display->grab_window == window)
+ meta_display_end_grab_op (display, CurrentTime);
+
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",
@@ -664,6 +740,14 @@ event_callback (XEvent *event,
}
break;
case UnmapNotify:
+ if (display->grab_op != META_GRAB_OP_NONE &&
+ display->grab_window == window)
+ meta_display_end_grab_op (display, CurrentTime);
+
+ /* Unfocus on UnmapNotify */
+ if (window)
+ meta_window_notify_focus (window, event);
+
if (!frame_was_receiver && window)
{
if (window->unmaps_pending == 0)
@@ -932,7 +1016,6 @@ static void
meta_spew_event (MetaDisplay *display,
XEvent *event)
{
-
const char *name = NULL;
char *extra = NULL;
char *winname;
@@ -1208,6 +1291,94 @@ meta_display_get_workspace_by_screen_index (MetaDisplay *display,
return NULL;
}
+Cursor
+meta_display_create_x_cursor (MetaDisplay *display,
+ MetaCursor cursor)
+{
+ Cursor xcursor;
+ guint glyph;
+
+ switch (cursor)
+ {
+ case META_CURSOR_DEFAULT:
+ glyph = XC_left_ptr;
+ break;
+ case META_CURSOR_NORTH_RESIZE:
+ glyph = XC_top_side;
+ break;
+ case META_CURSOR_SOUTH_RESIZE:
+ glyph = XC_bottom_side;
+ break;
+ case META_CURSOR_WEST_RESIZE:
+ glyph = XC_left_side;
+ break;
+ case META_CURSOR_EAST_RESIZE:
+ glyph = XC_right_side;
+ break;
+ case META_CURSOR_SE_RESIZE:
+ glyph = XC_bottom_right_corner;
+ break;
+ case META_CURSOR_SW_RESIZE:
+ glyph = XC_bottom_left_corner;
+ break;
+ case META_CURSOR_NE_RESIZE:
+ glyph = XC_top_left_corner;
+ break;
+ case META_CURSOR_NW_RESIZE:
+ glyph = XC_top_right_corner;
+ break;
+
+ default:
+ g_assert_not_reached ();
+ glyph = 0; /* silence compiler */
+ break;
+ }
+
+ xcursor = XCreateFontCursor (display->xdisplay, glyph);
+
+ return xcursor;
+}
+
+static Cursor
+xcursor_for_op (MetaDisplay *display,
+ MetaGrabOp op)
+{
+ MetaCursor cursor = META_CURSOR_DEFAULT;
+
+ switch (display->grab_op)
+ {
+ case META_GRAB_OP_RESIZING_SE:
+ cursor = META_CURSOR_SE_RESIZE;
+ break;
+ case META_GRAB_OP_RESIZING_S:
+ cursor = META_CURSOR_SOUTH_RESIZE;
+ break;
+ case META_GRAB_OP_RESIZING_SW:
+ cursor = META_CURSOR_SW_RESIZE;
+ break;
+ case META_GRAB_OP_RESIZING_N:
+ cursor = META_CURSOR_NORTH_RESIZE;
+ break;
+ case META_GRAB_OP_RESIZING_NE:
+ cursor = META_CURSOR_NE_RESIZE;
+ break;
+ case META_GRAB_OP_RESIZING_NW:
+ cursor = META_CURSOR_NW_RESIZE;
+ break;
+ case META_GRAB_OP_RESIZING_W:
+ cursor = META_CURSOR_WEST_RESIZE;
+ break;
+ case META_GRAB_OP_RESIZING_E:
+ cursor = META_CURSOR_EAST_RESIZE;
+ break;
+
+ default:
+ break;
+ }
+
+ return meta_display_create_x_cursor (display, cursor);
+}
+
gboolean
meta_display_begin_grab_op (MetaDisplay *display,
MetaWindow *window,
@@ -1215,13 +1386,13 @@ meta_display_begin_grab_op (MetaDisplay *display,
gboolean pointer_already_grabbed,
int button,
gulong modmask,
- Cursor cursor,
Time timestamp,
int root_x,
int root_y)
{
Window grabwindow;
-
+ Cursor cursor;
+
meta_verbose ("Doing grab op %d on window %s button %d pointer already grabbed: %d\n",
op, window->desc, button, pointer_already_grabbed);
@@ -1233,27 +1404,31 @@ meta_display_begin_grab_op (MetaDisplay *display,
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);
- }
+ display->grab_have_pointer = TRUE;
+
+ /* We XGrabPointer even if we already have an autograb,
+ * just to set the cursor and event mask
+ */
+
+ cursor = xcursor_for_op (display, op);
+
+ 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);
+
+ XFreeCursor (display->xdisplay, cursor);
if (!display->grab_have_pointer)
{
@@ -1283,7 +1458,6 @@ meta_display_begin_grab_op (MetaDisplay *display,
/* non-keyboard grab ops */
break;
}
-
display->grab_op = op;
display->grab_window = window;
@@ -1316,7 +1490,67 @@ meta_display_end_grab_op (MetaDisplay *display,
if (display->grab_have_keyboard)
meta_window_ungrab_all_keys (display->grab_window);
-
+
display->grab_window = NULL;
- display->grab_op = META_GRAB_OP_NONE;
+ display->grab_op = META_GRAB_OP_NONE;
+}
+
+void
+meta_display_grab_window_buttons (MetaDisplay *display,
+ Window xwindow)
+{
+ /* Grab Alt + button1 and Alt + button2 for moving window,
+ * and Alt + button3 for popping up window menu.
+ */
+ {
+ int i = 1;
+ while (i < 4)
+ {
+ int result;
+
+ meta_error_trap_push (display);
+ XGrabButton (display->xdisplay, i, Mod1Mask,
+ xwindow, False,
+ ButtonPressMask | ButtonReleaseMask |
+ PointerMotionMask | PointerMotionHintMask,
+ GrabModeAsync, GrabModeAsync,
+ False, None);
+ XSync (display->xdisplay, False);
+ result = meta_error_trap_pop (display);
+
+ if (result != Success)
+ meta_warning ("Failed to grab button %d with Mod1Mask for frame 0x%lx error code %d\n",
+ i, xwindow, result);
+
+#if 1
+ /* This is just for debugging, since I end up moving
+ * the Xnest otherwise ;-)
+ */
+ meta_error_trap_push (display);
+ result = XGrabButton (display->xdisplay, i, ControlMask,
+ xwindow, False,
+ ButtonPressMask | ButtonReleaseMask |
+ PointerMotionMask | PointerMotionHintMask,
+ GrabModeAsync, GrabModeAsync,
+ False, None);
+ XSync (display->xdisplay, False);
+ result = meta_error_trap_pop (display);
+
+ if (result != Success)
+ meta_warning ("Failed to grab button %d with ControlMask for frame 0x%lx error code %d\n",
+ i, xwindow, result);
+#endif
+
+ ++i;
+ }
+ }
}
+
+void
+meta_display_ungrab_window_buttons (MetaDisplay *display,
+ Window xwindow)
+{
+
+
+}
+
diff --git a/src/display.h b/src/display.h
index 11718ab..c04d965 100644
--- a/src/display.h
+++ b/src/display.h
@@ -119,7 +119,7 @@ struct _MetaDisplay
Window last_button_xwindow;
int last_button_num;
guint is_double_click : 1;
-
+
/* current window operation */
MetaGrabOp grab_op;
MetaWindow *grab_window;
@@ -163,19 +163,26 @@ MetaWorkspace* meta_display_get_workspace_by_index (MetaDisplay *displa
MetaWorkspace* meta_display_get_workspace_by_screen_index (MetaDisplay *display,
MetaScreen *screen,
int index);
+
+Cursor meta_display_create_x_cursor (MetaDisplay *display,
+ MetaCursor cursor);
+
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);
+void meta_display_grab_window_buttons (MetaDisplay *display,
+ Window xwindow);
+void meta_display_ungrab_window_buttons (MetaDisplay *display,
+ Window xwindow);
#endif
diff --git a/src/frames.c b/src/frames.c
index d0ab9b2..5af3a1a 100644
--- a/src/frames.c
+++ b/src/frames.c
@@ -137,20 +137,6 @@ static void meta_frames_calc_geometry (MetaFrames *frames,
static MetaUIFrame* meta_frames_lookup_window (MetaFrames *frames,
Window xwindow);
-static void meta_frames_begin_grab (MetaFrames *frames,
- MetaUIFrame *frame,
- MetaFrameStatus status,
- int start_button,
- int start_root_x,
- int start_root_y,
- int start_window_x,
- int start_window_y,
- int start_window_w,
- int start_window_h,
- guint32 timestamp);
-static void meta_frames_end_grab (MetaFrames *frames,
- guint32 timestamp);
-
static GdkRectangle* control_rect (MetaFrameControl control,
MetaFrameGeometry *fgeom);
@@ -238,6 +224,7 @@ meta_frames_class_init (MetaFramesClass *class)
widget_class->button_press_event = meta_frames_button_press_event;
widget_class->button_release_event = meta_frames_button_release_event;
widget_class->motion_notify_event = meta_frames_motion_notify_event;
+ widget_class->leave_notify_event = meta_frames_leave_notify_event;
INT_PROPERTY ("left_width", 6, _("Left edge"), _("Left window edge width"));
INT_PROPERTY ("right_width", 6, _("Right edge"), _("Right window edge width"));
@@ -291,8 +278,6 @@ meta_frames_init (MetaFrames *frames)
frames->frames = g_hash_table_new (unsigned_long_hash, unsigned_long_equal);
frames->tooltip_timeout = 0;
-
- frames->grab_status = META_FRAME_STATUS_NORMAL;
}
static void
@@ -711,55 +696,11 @@ meta_frames_manage_window (MetaFrames *frames,
/* Don't set event mask here, it's in frame.c */
- /* Grab Alt + button1 and Alt + button2 for moving window,
- * and Alt + button3 for popping up window menu.
- */
- {
- int i = 1;
- while (i < 4)
- {
- int result;
-
- gdk_error_trap_push ();
- XGrabButton (gdk_display, i, Mod1Mask,
- xwindow, False,
- ButtonPressMask | ButtonReleaseMask |
- PointerMotionMask | PointerMotionHintMask,
- GrabModeAsync, GrabModeAsync,
- False, None);
- XSync (gdk_display, False);
- result = gdk_error_trap_pop ();
-
- if (result != Success)
- meta_warning ("Failed to grab button %d with Mod1Mask for frame 0x%lx error code %d\n",
- i, xwindow, result);
-
-#if 1
- /* This is just for debugging, since I end up moving
- * the Xnest otherwise ;-)
- */
- gdk_error_trap_push ();
- result = XGrabButton (gdk_display, i, ControlMask,
- xwindow, False,
- ButtonPressMask | ButtonReleaseMask |
- PointerMotionMask | PointerMotionHintMask,
- GrabModeAsync, GrabModeAsync,
- False, None);
- XSync (gdk_display, False);
- result = gdk_error_trap_pop ();
-
- if (result != Success)
- meta_warning ("Failed to grab button %d with ControlMask for frame 0x%lx error code %d\n",
- i, xwindow, result);
-#endif
-
- ++i;
- }
- }
-
frame->xwindow = xwindow;
frame->layout = NULL;
+ meta_core_grab_buttons (gdk_display, frame->xwindow);
+
g_hash_table_insert (frames->frames, &frame->xwindow, frame);
}
@@ -780,9 +721,6 @@ meta_frames_unmanage_window (MetaFrames *frames,
if (frames->last_motion_frame == frame)
frames->last_motion_frame = NULL;
- if (frames->grab_frame == frame)
- meta_frames_end_grab (frames, GDK_CURRENT_TIME);
-
g_hash_table_remove (frames->frames, &frame->xwindow);
g_object_unref (G_OBJECT (frame->window));
@@ -802,12 +740,6 @@ meta_frames_realize (GtkWidget *widget)
MetaFrames *frames;
frames = META_FRAMES (widget);
-
- frames->south_resize_cursor = gdk_cursor_new (GDK_BOTTOM_SIDE);
- frames->east_resize_cursor = gdk_cursor_new (GDK_RIGHT_SIDE);
- frames->west_resize_cursor = gdk_cursor_new (GDK_LEFT_SIDE);
- frames->se_resize_cursor = gdk_cursor_new (GDK_BOTTOM_RIGHT_CORNER);
- frames->sw_resize_cursor = gdk_cursor_new (GDK_BOTTOM_LEFT_CORNER);
if (GTK_WIDGET_CLASS (parent_class)->realize)
GTK_WIDGET_CLASS (parent_class)->realize (widget);
@@ -819,18 +751,6 @@ meta_frames_unrealize (GtkWidget *widget)
MetaFrames *frames;
frames = META_FRAMES (widget);
-
- gdk_cursor_unref (frames->south_resize_cursor);
- gdk_cursor_unref (frames->east_resize_cursor);
- gdk_cursor_unref (frames->west_resize_cursor);
- gdk_cursor_unref (frames->se_resize_cursor);
- gdk_cursor_unref (frames->sw_resize_cursor);
-
- frames->south_resize_cursor = NULL;
- frames->east_resize_cursor = NULL;
- frames->west_resize_cursor = NULL;
- frames->se_resize_cursor = NULL;
- frames->sw_resize_cursor = NULL;
if (GTK_WIDGET_CLASS (parent_class)->unrealize)
GTK_WIDGET_CLASS (parent_class)->unrealize (widget);
@@ -1039,258 +959,6 @@ clear_tip (MetaFrames *frames)
meta_fixed_tip_hide ();
}
-static GdkCursor*
-cursor_for_resize (MetaFrames *frames,
- MetaFrameStatus status)
-{
- GdkCursor *cursor;
-
- cursor = NULL;
- switch (status)
- {
- case META_FRAME_STATUS_RESIZING_E:
- cursor = frames->east_resize_cursor;
- break;
- case META_FRAME_STATUS_RESIZING_W:
- cursor = frames->west_resize_cursor;
- break;
- case META_FRAME_STATUS_RESIZING_S:
- cursor = frames->south_resize_cursor;
- break;
- case META_FRAME_STATUS_RESIZING_SE:
- cursor = frames->se_resize_cursor;
- break;
- case META_FRAME_STATUS_RESIZING_SW:
- cursor = frames->sw_resize_cursor;
- break;
-
- case META_FRAME_STATUS_RESIZING_N:
- case META_FRAME_STATUS_RESIZING_NE:
- case META_FRAME_STATUS_RESIZING_NW:
- break;
-
- default:
- g_assert_not_reached ();
- break;
- }
-
- return cursor;
-}
-
-static void
-meta_frames_begin_grab (MetaFrames *frames,
- MetaUIFrame *frame,
- MetaFrameStatus status,
- int start_button,
- int start_root_x,
- int start_root_y,
- int start_window_x,
- int start_window_y,
- int start_window_w,
- int start_window_h,
- guint32 timestamp)
-{
- GdkCursor *cursor;
-
- g_return_if_fail (frames->grab_frame == NULL);
-
- clear_tip (frames);
-
- cursor = NULL;
- switch (status)
- {
- case META_FRAME_STATUS_MOVING:
- break;
-
- case META_FRAME_STATUS_RESIZING_E:
- case META_FRAME_STATUS_RESIZING_W:
- case META_FRAME_STATUS_RESIZING_S:
- case META_FRAME_STATUS_RESIZING_SE:
- case META_FRAME_STATUS_RESIZING_SW:
- case META_FRAME_STATUS_RESIZING_N:
- case META_FRAME_STATUS_RESIZING_NE:
- case META_FRAME_STATUS_RESIZING_NW:
- cursor = cursor_for_resize (frames, status);
- break;
-
- case META_FRAME_STATUS_CLICKING_MINIMIZE:
- break;
-
- case META_FRAME_STATUS_CLICKING_MAXIMIZE:
- break;
-
- case META_FRAME_STATUS_CLICKING_DELETE:
- break;
-
- case META_FRAME_STATUS_CLICKING_MENU:
- break;
-
- case META_FRAME_STATUS_NORMAL:
- break;
- }
-
- /* This grab isn't needed I don't think */
- if (gdk_pointer_grab (frame->window,
- FALSE,
- GDK_BUTTON_RELEASE_MASK | GDK_BUTTON_PRESS_MASK |
- GDK_POINTER_MOTION_HINT_MASK | GDK_POINTER_MOTION_MASK,
- NULL,
- cursor,
- timestamp) == GDK_GRAB_SUCCESS)
- {
- frames->grab_frame = frame;
- frames->grab_status = status;
- frames->start_button = start_button;
- frames->start_root_x = start_root_x;
- frames->start_root_y = start_root_y;
- frames->start_window_x = start_window_x;
- frames->start_window_y = start_window_y;
- frames->start_window_w = start_window_w;
- frames->start_window_h = start_window_h;
- }
-}
-
-static void
-meta_frames_end_grab (MetaFrames *frames,
- guint32 timestamp)
-{
- if (frames->grab_frame)
- {
- frames->grab_frame = NULL;
- frames->grab_status = META_FRAME_STATUS_NORMAL;
- gdk_pointer_ungrab (timestamp);
- }
-}
-
-static void
-frame_query_root_pointer (MetaUIFrame *frame,
- int *x, int *y)
-{
- Window root_return, child_return;
- int root_x_return, root_y_return;
- int win_x_return, win_y_return;
- unsigned int mask_return;
-
- XQueryPointer (gdk_display,
- frame->xwindow,
- &root_return,
- &child_return,
- &root_x_return,
- &root_y_return,
- &win_x_return,
- &win_y_return,
- &mask_return);
-
- if (x)
- *x = root_x_return;
- if (y)
- *y = root_y_return;
-}
-
-static void
-update_move (MetaFrames *frames,
- MetaUIFrame *frame,
- int x,
- int y)
-{
- int dx, dy;
-
- dx = x - frames->start_root_x;
- dy = y - frames->start_root_y;
-
- meta_core_user_move (gdk_display,
- frame->xwindow,
- frames->start_window_x + dx,
- frames->start_window_y + dy);
-}
-
-static void
-update_resize (MetaFrames *frames,
- MetaUIFrame *frame,
- MetaFrameStatus status,
- int x, int y)
-{
- int dx, dy;
- int new_w, new_h;
- int gravity;
-
- dx = x - frames->start_root_x;
- dy = y - frames->start_root_y;
-
- new_w = frames->start_window_w;
- new_h = frames->start_window_h;
-
- switch (status)
- {
- case META_FRAME_STATUS_RESIZING_SE:
- case META_FRAME_STATUS_RESIZING_NE:
- case META_FRAME_STATUS_RESIZING_E:
- new_w += dx;
- break;
-
- case META_FRAME_STATUS_RESIZING_NW:
- case META_FRAME_STATUS_RESIZING_SW:
- case META_FRAME_STATUS_RESIZING_W:
- new_w -= dx;
- break;
-
- default:
- break;
- }
-
- switch (status)
- {
- case META_FRAME_STATUS_RESIZING_SE:
- case META_FRAME_STATUS_RESIZING_S:
- case META_FRAME_STATUS_RESIZING_SW:
- new_h += dy;
- break;
-
- case META_FRAME_STATUS_RESIZING_N:
- case META_FRAME_STATUS_RESIZING_NE:
- case META_FRAME_STATUS_RESIZING_NW:
- new_h -= dy;
- break;
- default:
- break;
- }
-
- /* compute gravity of client during operation */
- gravity = -1;
- switch (status)
- {
- case META_FRAME_STATUS_RESIZING_SE:
- gravity = NorthWestGravity;
- break;
- case META_FRAME_STATUS_RESIZING_S:
- gravity = NorthGravity;
- break;
- case META_FRAME_STATUS_RESIZING_SW:
- gravity = NorthEastGravity;
- break;
- case META_FRAME_STATUS_RESIZING_N:
- gravity = SouthGravity;
- break;
- case META_FRAME_STATUS_RESIZING_NE:
- gravity = SouthWestGravity;
- break;
- case META_FRAME_STATUS_RESIZING_NW:
- gravity = SouthEastGravity;
- break;
- case META_FRAME_STATUS_RESIZING_E:
- gravity = WestGravity;
- break;
- case META_FRAME_STATUS_RESIZING_W:
- gravity = EastGravity;
- break;
- default:
- g_assert_not_reached ();
- break;
- }
-
- meta_core_user_resize (gdk_display, frame->xwindow, gravity, new_w, new_h);
-}
-
static void
redraw_control (MetaFrames *frames,
MetaUIFrame *frame,
@@ -1324,6 +992,10 @@ meta_frames_button_press_event (GtkWidget *widget,
MetaFrameControl control;
frames = META_FRAMES (widget);
+
+ /* Remember that the display may have already done something with this event.
+ * If so there's probably a GrabOp in effect.
+ */
frame = meta_frames_lookup_window (frames, GDK_WINDOW_XID (event->window));
if (frame == NULL)
@@ -1333,6 +1005,9 @@ meta_frames_button_press_event (GtkWidget *widget,
control = get_control (frames, frame, event->x, event->y);
+ /* We want to shade even if we have a GrabOp, since we'll have a move grab
+ * if we double click the titlebar.
+ */
if (control == META_FRAME_CONTROL_TITLE &&
event->button == 1 &&
event->type == GDK_2BUTTON_PRESS)
@@ -1354,15 +1029,9 @@ meta_frames_button_press_event (GtkWidget *widget,
return TRUE;
}
- if (frames->grab_frame != NULL)
- return FALSE; /* already up to something */
-
- if (event->button == 1)
- {
- meta_core_user_raise (gdk_display, frame->xwindow);
- meta_core_user_focus (gdk_display, frame->xwindow,
- event->time);
- }
+ if (meta_core_get_grab_op (gdk_display) !=
+ META_GRAB_OP_NONE)
+ return FALSE; /* already up to something */
if (event->button == 1 &&
(control == META_FRAME_CONTROL_MAXIMIZE ||
@@ -1370,36 +1039,40 @@ meta_frames_button_press_event (GtkWidget *widget,
control == META_FRAME_CONTROL_DELETE ||
control == META_FRAME_CONTROL_MENU))
{
- MetaFrameStatus status = META_FRAME_STATUS_NORMAL;
+ MetaGrabOp op = META_GRAB_OP_NONE;
switch (control)
{
case META_FRAME_CONTROL_MINIMIZE:
- status = META_FRAME_STATUS_CLICKING_MINIMIZE;
+ op = META_GRAB_OP_CLICKING_MINIMIZE;
break;
case META_FRAME_CONTROL_MAXIMIZE:
- status = META_FRAME_STATUS_CLICKING_MAXIMIZE;
+ op = META_GRAB_OP_CLICKING_MAXIMIZE;
break;
case META_FRAME_CONTROL_DELETE:
- status = META_FRAME_STATUS_CLICKING_DELETE;
+ op = META_GRAB_OP_CLICKING_DELETE;
break;
case META_FRAME_CONTROL_MENU:
- status = META_FRAME_STATUS_CLICKING_MENU;
+ op = META_GRAB_OP_CLICKING_MENU;
break;
default:
g_assert_not_reached ();
break;
}
- meta_frames_begin_grab (frames, frame,
- status,
- event->button,
- 0, 0, 0, 0, 0, 0, /* not needed */
- event->time);
+ meta_core_begin_grab_op (gdk_display,
+ frame->xwindow,
+ op,
+ TRUE,
+ event->button,
+ 0,
+ event->time,
+ event->x_root,
+ event->y_root);
redraw_control (frames, frame, control);
- if (status == META_FRAME_STATUS_CLICKING_MENU)
+ if (op == META_GRAB_OP_CLICKING_MENU)
{
MetaFrameGeometry fgeom;
GdkRectangle *rect;
@@ -1431,58 +1104,50 @@ meta_frames_button_press_event (GtkWidget *widget,
control == META_FRAME_CONTROL_RESIZE_E ||
control == META_FRAME_CONTROL_RESIZE_W))
{
- int w, h, x, y;
- MetaFrameStatus status;
-
- meta_core_get_size (gdk_display,
- frame->xwindow,
- &w, &h);
+ MetaGrabOp op;
- meta_core_get_position (gdk_display,
- frame->xwindow,
- &x, &y);
-
- status = META_FRAME_STATUS_NORMAL;
+ op = META_GRAB_OP_NONE;
switch (control)
{
case META_FRAME_CONTROL_RESIZE_SE:
- status = META_FRAME_STATUS_RESIZING_SE;
+ op = META_GRAB_OP_RESIZING_SE;
break;
case META_FRAME_CONTROL_RESIZE_S:
- status = META_FRAME_STATUS_RESIZING_S;
+ op = META_GRAB_OP_RESIZING_S;
break;
case META_FRAME_CONTROL_RESIZE_SW:
- status = META_FRAME_STATUS_RESIZING_SW;
+ op = META_GRAB_OP_RESIZING_SW;
break;
case META_FRAME_CONTROL_RESIZE_NE:
- status = META_FRAME_STATUS_RESIZING_NE;
+ op = META_GRAB_OP_RESIZING_NE;
break;
case META_FRAME_CONTROL_RESIZE_N:
- status = META_FRAME_STATUS_RESIZING_N;
+ op = META_GRAB_OP_RESIZING_N;
break;
case META_FRAME_CONTROL_RESIZE_NW:
- status = META_FRAME_STATUS_RESIZING_NW;
+ op = META_GRAB_OP_RESIZING_NW;
break;
case META_FRAME_CONTROL_RESIZE_E:
- status = META_FRAME_STATUS_RESIZING_E;
+ op = META_GRAB_OP_RESIZING_E;
break;
case META_FRAME_CONTROL_RESIZE_W:
- status = META_FRAME_STATUS_RESIZING_W;
+ op = META_GRAB_OP_RESIZING_W;
break;
default:
g_assert_not_reached ();
break;
}
-
- meta_frames_begin_grab (frames, frame,
- status,
- event->button,
- event->x_root,
- event->y_root,
- x, y,
- w, h,
- event->time);
+
+ meta_core_begin_grab_op (gdk_display,
+ frame->xwindow,
+ op,
+ TRUE,
+ event->button,
+ 0,
+ event->time,
+ event->x_root,
+ event->y_root);
}
else if (((control == META_FRAME_CONTROL_TITLE ||
control == META_FRAME_CONTROL_NONE) &&
@@ -1494,24 +1159,16 @@ meta_frames_button_press_event (GtkWidget *widget,
flags = meta_core_get_frame_flags (gdk_display, frame->xwindow);
if (flags & META_FRAME_ALLOWS_MOVE)
- {
- int x, y, w, h;
-
- meta_core_get_position (gdk_display,
- frame->xwindow,
- &x, &y);
-
- meta_core_get_size (gdk_display,
- frame->xwindow,
- &w, &h);
-
- meta_frames_begin_grab (frames, frame,
- META_FRAME_STATUS_MOVING,
- event->button,
- event->x_root,
- event->y_root,
- x, y, w, h,
- event->time);
+ {
+ meta_core_begin_grab_op (gdk_display,
+ frame->xwindow,
+ META_GRAB_OP_MOVING,
+ TRUE,
+ event->button,
+ 0,
+ event->time,
+ event->x_root,
+ event->y_root);
}
}
else if (event->button == 3)
@@ -1521,7 +1178,7 @@ meta_frames_button_press_event (GtkWidget *widget,
event->x_root,
event->y_root,
event->button,
- event->time);
+ event->time);
}
return TRUE;
@@ -1530,11 +1187,26 @@ meta_frames_button_press_event (GtkWidget *widget,
void
meta_frames_notify_menu_hide (MetaFrames *frames)
{
- if (frames->grab_status == META_FRAME_STATUS_CLICKING_MENU)
+ if (meta_core_get_grab_op (gdk_display) ==
+ META_GRAB_OP_CLICKING_MENU)
{
- redraw_control (frames, frames->grab_frame,
- META_FRAME_CONTROL_MENU);
- meta_frames_end_grab (frames, GDK_CURRENT_TIME);
+ Window grab_frame;
+
+ grab_frame = meta_core_get_grab_frame (gdk_display);
+
+ if (grab_frame != None)
+ {
+ MetaUIFrame *frame;
+
+ frame = meta_frames_lookup_window (frames, grab_frame);
+
+ if (frame)
+ {
+ redraw_control (frames, frame,
+ META_FRAME_CONTROL_MENU);
+ meta_core_end_grab_op (gdk_display, CurrentTime);
+ }
+ }
}
}
@@ -1544,7 +1216,8 @@ meta_frames_button_release_event (GtkWidget *widget,
{
MetaUIFrame *frame;
MetaFrames *frames;
-
+ MetaGrabOp op;
+
frames = META_FRAMES (widget);
frame = meta_frames_lookup_window (frames, GDK_WINDOW_XID (event->window));
@@ -1552,34 +1225,26 @@ meta_frames_button_release_event (GtkWidget *widget,
return FALSE;
clear_tip (frames);
-
- if (frames->grab_frame == frame &&
- frames->start_button == event->button)
+
+ op = meta_core_get_grab_op (gdk_display);
+
+ if (op == META_GRAB_OP_NONE)
+ return FALSE;
+
+ /* We only handle the releases we handled the presses for (things
+ * involving frame controls). Window ops that don't require a
+ * frame are handled in the Xlib part of the code, display.c/window.c
+ */
+ if (frame->xwindow == meta_core_get_grab_frame (gdk_display) &&
+ event->button == meta_core_get_grab_button (gdk_display))
{
- MetaFrameStatus status;
+ gboolean end_grab;
- status = frames->grab_status;
-
- meta_frames_end_grab (frames, event->time);
+ end_grab = FALSE;
- switch (status)
+ switch (op)
{
- case META_FRAME_STATUS_MOVING:
- update_move (frames, frame, event->x_root, event->y_root);
- break;
-
- case META_FRAME_STATUS_RESIZING_E:
- case META_FRAME_STATUS_RESIZING_W:
- case META_FRAME_STATUS_RESIZING_S:
- case META_FRAME_STATUS_RESIZING_N:
- case META_FRAME_STATUS_RESIZING_SE:
- case META_FRAME_STATUS_RESIZING_SW:
- case META_FRAME_STATUS_RESIZING_NE:
- case META_FRAME_STATUS_RESIZING_NW:
- update_resize (frames, frame, status, event->x_root, event->y_root);
- break;
-
- case META_FRAME_STATUS_CLICKING_MINIMIZE:
+ case META_GRAB_OP_CLICKING_MINIMIZE:
if (point_in_control (frames, frame,
META_FRAME_CONTROL_MINIMIZE,
event->x, event->y))
@@ -1587,9 +1252,10 @@ meta_frames_button_release_event (GtkWidget *widget,
redraw_control (frames, frame,
META_FRAME_CONTROL_MINIMIZE);
+ end_grab = TRUE;
break;
- case META_FRAME_STATUS_CLICKING_MAXIMIZE:
+ case META_GRAB_OP_CLICKING_MAXIMIZE:
if (point_in_control (frames, frame,
META_FRAME_CONTROL_MAXIMIZE,
event->x, event->y))
@@ -1602,25 +1268,31 @@ meta_frames_button_release_event (GtkWidget *widget,
}
redraw_control (frames, frame,
META_FRAME_CONTROL_MAXIMIZE);
+ end_grab = TRUE;
break;
- case META_FRAME_STATUS_CLICKING_DELETE:
+ case META_GRAB_OP_CLICKING_DELETE:
if (point_in_control (frames, frame,
META_FRAME_CONTROL_DELETE,
event->x, event->y))
meta_core_delete (gdk_display, frame->xwindow, event->time);
redraw_control (frames, frame,
META_FRAME_CONTROL_DELETE);
+ end_grab = TRUE;
break;
- case META_FRAME_STATUS_CLICKING_MENU:
+ case META_GRAB_OP_CLICKING_MENU:
redraw_control (frames, frame,
META_FRAME_CONTROL_MENU);
+ end_grab = TRUE;
break;
-
- case META_FRAME_STATUS_NORMAL:
+
+ default:
break;
}
+
+ if (end_grab)
+ meta_core_end_grab_op (gdk_display, event->time);
}
return TRUE;
@@ -1643,46 +1315,25 @@ meta_frames_motion_notify_event (GtkWidget *widget,
frames->last_motion_frame = frame;
- switch (frames->grab_status)
+ switch (meta_core_get_grab_op (gdk_display))
{
- case META_FRAME_STATUS_MOVING:
- {
- int x, y;
- frame_query_root_pointer (frame, &x, &y);
- update_move (frames, frame, x, y);
- }
- break;
- case META_FRAME_STATUS_RESIZING_E:
- case META_FRAME_STATUS_RESIZING_W:
- case META_FRAME_STATUS_RESIZING_S:
- case META_FRAME_STATUS_RESIZING_N:
- case META_FRAME_STATUS_RESIZING_SE:
- case META_FRAME_STATUS_RESIZING_SW:
- case META_FRAME_STATUS_RESIZING_NE:
- case META_FRAME_STATUS_RESIZING_NW:
- {
- int x, y;
- frame_query_root_pointer (frame, &x, &y);
- update_resize (frames, frame, frames->grab_status, x, y);
- }
+ case META_GRAB_OP_CLICKING_MENU:
+ case META_GRAB_OP_CLICKING_DELETE:
+ case META_GRAB_OP_CLICKING_MINIMIZE:
+ case META_GRAB_OP_CLICKING_MAXIMIZE:
break;
-
- case META_FRAME_STATUS_CLICKING_MENU:
- case META_FRAME_STATUS_CLICKING_DELETE:
- case META_FRAME_STATUS_CLICKING_MINIMIZE:
- case META_FRAME_STATUS_CLICKING_MAXIMIZE:
- break;
- case META_FRAME_STATUS_NORMAL:
+
+ case META_GRAB_OP_NONE:
{
MetaFrameControl control;
- GdkCursor *cursor;
int x, y;
-
+ MetaCursor cursor;
+
gdk_window_get_pointer (frame->window, &x, &y, NULL);
control = get_control (frames, frame, x, y);
- cursor = NULL;
+ cursor = META_CURSOR_DEFAULT;
switch (control)
{
@@ -1699,37 +1350,42 @@ meta_frames_motion_notify_event (GtkWidget *widget,
case META_FRAME_CONTROL_MAXIMIZE:
break;
case META_FRAME_CONTROL_RESIZE_SE:
- cursor = frames->se_resize_cursor;
+ cursor = META_CURSOR_SE_RESIZE;
break;
case META_FRAME_CONTROL_RESIZE_S:
- cursor = frames->south_resize_cursor;
+ cursor = META_CURSOR_SOUTH_RESIZE;
break;
case META_FRAME_CONTROL_RESIZE_SW:
- cursor = frames->sw_resize_cursor;
+ cursor = META_CURSOR_SW_RESIZE;
break;
case META_FRAME_CONTROL_RESIZE_N:
+ cursor = META_CURSOR_NORTH_RESIZE;
break;
case META_FRAME_CONTROL_RESIZE_NE:
+ cursor = META_CURSOR_NE_RESIZE;
break;
case META_FRAME_CONTROL_RESIZE_NW:
+ cursor = META_CURSOR_NW_RESIZE;
break;
case META_FRAME_CONTROL_RESIZE_W:
- cursor = frames->west_resize_cursor;
+ cursor = META_CURSOR_WEST_RESIZE;
break;
case META_FRAME_CONTROL_RESIZE_E:
- cursor = frames->east_resize_cursor;
+ cursor = META_CURSOR_EAST_RESIZE;
break;
- }
+ }
- if (cursor != frames->current_cursor)
- {
- gdk_window_set_cursor (frame->window, cursor);
- frames->current_cursor = cursor;
- }
+ /* set/unset the prelight cursor */
+ meta_core_set_screen_cursor (gdk_display,
+ frame->xwindow,
+ cursor);
queue_tip (frames);
}
break;
+
+ default:
+ break;
}
return TRUE;
@@ -1747,9 +1403,6 @@ meta_frames_destroy_event (GtkWidget *widget,
frame = meta_frames_lookup_window (frames, GDK_WINDOW_XID (event->window));
if (frame == NULL)
return FALSE;
-
- if (frames->grab_frame == frame)
- meta_frames_end_grab (frames, GDK_CURRENT_TIME);
return TRUE;
}
@@ -1890,23 +1543,26 @@ draw_control_bg (MetaFrames *frames,
GdkRectangle *rect;
GtkWidget *widget;
gboolean draw = FALSE;
+ Window grab_frame;
widget = GTK_WIDGET (frames);
- if (frame == frames->grab_frame)
+ grab_frame = meta_core_get_grab_frame (gdk_display);
+
+ if (frame->xwindow == grab_frame)
{
- switch (frames->grab_status)
+ switch (meta_core_get_grab_op (gdk_display))
{
- case META_FRAME_STATUS_CLICKING_MENU:
+ case META_GRAB_OP_CLICKING_MENU:
draw = control == META_FRAME_CONTROL_MENU;
break;
- case META_FRAME_STATUS_CLICKING_DELETE:
+ case META_GRAB_OP_CLICKING_DELETE:
draw = control == META_FRAME_CONTROL_DELETE;
break;
- case META_FRAME_STATUS_CLICKING_MAXIMIZE:
+ case META_GRAB_OP_CLICKING_MAXIMIZE:
draw = control == META_FRAME_CONTROL_MAXIMIZE;
break;
- case META_FRAME_STATUS_CLICKING_MINIMIZE:
+ case META_GRAB_OP_CLICKING_MINIMIZE:
draw = control == META_FRAME_CONTROL_MINIMIZE;
break;
default:
@@ -2169,11 +1825,11 @@ meta_frames_leave_notify_event (GtkWidget *widget,
if (frame == NULL)
return FALSE;
- if (frames->current_cursor)
- {
- gdk_window_set_cursor (frame->window, NULL);
- frames->current_cursor = NULL;
- }
+ clear_tip (frames);
+
+ meta_core_set_screen_cursor (gdk_display,
+ frame->xwindow,
+ META_CURSOR_DEFAULT);
return TRUE;
}
@@ -2254,9 +1910,6 @@ meta_frames_unmap_event (GtkWidget *widget,
frame = meta_frames_lookup_window (frames, GDK_WINDOW_XID (event->window));
if (frame == NULL)
return FALSE;
-
- if (frames->grab_frame == frame)
- meta_frames_end_grab (frames, GDK_CURRENT_TIME);
return TRUE;
}
@@ -2309,9 +1962,6 @@ meta_frames_window_state_event (GtkWidget *widget,
return TRUE;
}
-
-
-
static GdkRectangle*
control_rect (MetaFrameControl control,
MetaFrameGeometry *fgeom)
@@ -2447,13 +2097,3 @@ get_control (MetaFrames *frames,
return META_FRAME_CONTROL_NONE;
}
-
-Window
-meta_frames_get_moving_frame (MetaFrames *frames)
-{
- if (frames->grab_frame &&
- frames->grab_status == META_FRAME_STATUS_MOVING)
- return frames->grab_frame->xwindow;
- else
- return None;
-}
diff --git a/src/frames.h b/src/frames.h
index b53325e..4531d2a 100644
--- a/src/frames.h
+++ b/src/frames.h
@@ -44,24 +44,6 @@ typedef enum
META_FRAME_CONTROL_RESIZE_E
} MetaFrameControl;
-typedef enum
-{
- META_FRAME_STATUS_NORMAL,
- META_FRAME_STATUS_MOVING,
- META_FRAME_STATUS_CLICKING_MINIMIZE,
- META_FRAME_STATUS_CLICKING_MAXIMIZE,
- META_FRAME_STATUS_CLICKING_DELETE,
- META_FRAME_STATUS_CLICKING_MENU,
- META_FRAME_STATUS_RESIZING_SE,
- META_FRAME_STATUS_RESIZING_S,
- META_FRAME_STATUS_RESIZING_SW,
- META_FRAME_STATUS_RESIZING_N,
- META_FRAME_STATUS_RESIZING_NE,
- META_FRAME_STATUS_RESIZING_NW,
- META_FRAME_STATUS_RESIZING_W,
- META_FRAME_STATUS_RESIZING_E
-} MetaFrameStatus;
-
/* This is one widget that manages all the window frames
* as subwindows.
*/
@@ -99,26 +81,6 @@ struct _MetaFrames
guint tooltip_timeout;
MetaUIFrame *last_motion_frame;
-
- GdkCursor *south_resize_cursor;
- GdkCursor *west_resize_cursor;
- GdkCursor *east_resize_cursor;
- GdkCursor *se_resize_cursor;
- GdkCursor *sw_resize_cursor;
-
- GdkCursor *current_cursor;
-
- /* The below is all for grabs */
- MetaFrameStatus grab_status;
- MetaUIFrame *grab_frame;
- /* initial mouse position for drags */
- int start_root_x, start_root_y;
- /* initial window position for drags */
- int start_window_x, start_window_y;
- /* initial window size for drags */
- int start_window_w, start_window_h;
- /* button doing the dragging */
- int start_button;
};
struct _MetaFramesClass
diff --git a/src/keybindings.c b/src/keybindings.c
index f91c7d0..177b6d6 100644
--- a/src/keybindings.c
+++ b/src/keybindings.c
@@ -395,7 +395,7 @@ meta_display_process_key_event (MetaDisplay *display,
return;
handled = FALSE;
-
+
if (display->grab_op == META_GRAB_OP_KEYBOARD_MOVING &&
display->grab_window == window)
{
@@ -408,7 +408,7 @@ meta_display_process_key_event (MetaDisplay *display,
return; /* don't care about releases */
if (window == NULL)
- meta_bug ("NULL window while META_GRAB_OP_MOVING\n");
+ meta_bug ("NULL window while doing keyboard grab op\n");
meta_window_get_position (window, &x, &y);
@@ -486,8 +486,8 @@ meta_display_process_key_event (MetaDisplay *display,
if (handled)
meta_window_move (window, x, y);
- }
-
+ }
+
/* end grab if a key that isn't used gets pressed */
if (!handled)
{
@@ -512,20 +512,14 @@ handle_activate_workspace (MetaDisplay *display,
if (workspace)
{
- Window move_frame;
MetaWindow *move_window;
move_window = NULL;
- move_frame = meta_ui_get_moving_frame (workspace->screen->ui);
+ if (display->grab_op == META_GRAB_OP_MOVING)
+ move_window = display->grab_window;
- if (move_frame != None)
+ if (move_window != NULL)
{
- move_window = meta_display_lookup_x_window (display, move_frame);
-
- if (move_window == NULL ||
- move_window->frame == NULL)
- meta_bug ("No move_frame window 0x%lx!\n", move_frame);
-
if (move_window->on_all_workspaces)
move_window = NULL; /* don't move it after all */
diff --git a/src/screen.c b/src/screen.c
index 83d1c9f..7f704ed 100644
--- a/src/screen.c
+++ b/src/screen.c
@@ -28,7 +28,6 @@
#include "keybindings.h"
#include "stack.h"
-#include <X11/cursorfont.h>
#include <X11/Xatom.h>
#include <locale.h>
#include <string.h>
@@ -113,7 +112,6 @@ meta_screen_new (MetaDisplay *display,
MetaScreen *screen;
Window xroot;
Display *xdisplay;
- Cursor cursor;
/* Only display->name, display->xdisplay, and display->error_traps
* can really be used in this function, since normally screens are
@@ -151,10 +149,6 @@ meta_screen_new (MetaDisplay *display,
number, display->name);
return NULL;
}
-
- cursor = XCreateFontCursor (display->xdisplay, XC_left_ptr);
- XDefineCursor (display->xdisplay, xroot, cursor);
- XFreeCursor (display->xdisplay, cursor);
screen = g_new (MetaScreen, 1);
@@ -165,6 +159,9 @@ meta_screen_new (MetaDisplay *display,
screen->xroot = xroot;
screen->width = WidthOfScreen (screen->xscreen);
screen->height = HeightOfScreen (screen->xscreen);
+ screen->current_cursor = -1; /* invalid/unset */
+
+ meta_screen_set_cursor (screen, META_CURSOR_DEFAULT);
if (display->leader_window == None)
display->leader_window = XCreateSimpleWindow (display->xdisplay,
@@ -400,3 +397,19 @@ meta_screen_get_n_workspaces (MetaScreen *screen)
return i;
}
+
+void
+meta_screen_set_cursor (MetaScreen *screen,
+ MetaCursor cursor)
+{
+ Cursor xcursor;
+
+ if (cursor == screen->current_cursor)
+ return;
+
+ screen->current_cursor = cursor;
+
+ xcursor = meta_display_create_x_cursor (screen->display, cursor);
+ XDefineCursor (screen->display->xdisplay, screen->xroot, xcursor);
+ XFreeCursor (screen->display->xdisplay, xcursor);
+}
diff --git a/src/screen.h b/src/screen.h
index c733d63..ce0a4ba 100644
--- a/src/screen.h
+++ b/src/screen.h
@@ -43,6 +43,8 @@ struct _MetaScreen
MetaWorkspace *active_workspace;
MetaStack *stack;
+
+ MetaCursor current_cursor;
};
MetaScreen* meta_screen_new (MetaDisplay *display,
@@ -58,6 +60,8 @@ void meta_screen_queue_window_resizes (MetaScreen *scre
int meta_screen_get_n_workspaces (MetaScreen *screen);
+void meta_screen_set_cursor (MetaScreen *screen,
+ MetaCursor cursor);
#endif
diff --git a/src/ui.c b/src/ui.c
index f50dfc4..c9c66b5 100644
--- a/src/ui.c
+++ b/src/ui.c
@@ -151,12 +151,6 @@ meta_ui_remove_frame (MetaUI *ui,
meta_frames_unmanage_window (ui->frames, xwindow);
}
-Window
-meta_ui_get_moving_frame (MetaUI *ui)
-{
- return meta_frames_get_moving_frame (ui->frames);
-}
-
void
meta_ui_map_frame (MetaUI *ui,
Window xwindow)
diff --git a/src/ui.h b/src/ui.h
index 04d147b..874fdfc 100644
--- a/src/ui.h
+++ b/src/ui.h
@@ -54,8 +54,6 @@ void meta_ui_add_frame (MetaUI *ui,
Window xwindow);
void meta_ui_remove_frame (MetaUI *ui,
Window xwindow);
-
-Window meta_ui_get_moving_frame (MetaUI *ui);
/* GDK insists on tracking map/unmap */
diff --git a/src/window.c b/src/window.c
index 3136e06..9e0dc71 100644
--- a/src/window.c
+++ b/src/window.c
@@ -2876,7 +2876,7 @@ update_sm_hints (MetaWindow *window)
window->display->atom_sm_client_id,
&window->sm_client_id);
- meta_verbose ("Window %s client leader: 0x%ld SM_CLIENT_ID: '%s'\n",
+ meta_verbose ("Window %s client leader: 0x%lx SM_CLIENT_ID: '%s'\n",
window->desc, window->xclient_leader, window->sm_client_id);
}
else
@@ -2915,7 +2915,7 @@ update_transient_for (MetaWindow *window)
window->xtransient_for = w;
if (window->xtransient_for != None)
- meta_verbose ("Window %s transient for 0x%ld\n", window->desc,
+ meta_verbose ("Window %s transient for 0x%lx\n", window->desc,
window->xtransient_for);
else
meta_verbose ("Window %s is not transient\n", window->desc);
diff --git a/src/window.h b/src/window.h
index 9bd3b8b..7421732 100644
--- a/src/window.h
+++ b/src/window.h
@@ -297,4 +297,7 @@ gboolean meta_window_shares_some_workspace (MetaWindow *window,
void meta_window_set_gravity (MetaWindow *window,
int gravity);
+void meta_window_handle_mouse_grab_op_event (MetaWindow *window,
+ XEvent *event);
+
#endif