diff --git a/README b/README index 6adaa4332..1324bc6f6 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. - Metacity has a "no crackrock" policy, with some exceptions + 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. + + 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 af8070593..87f830c22 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 07c5e98e9..9e709074d 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 75bd8f763..3b291cea3 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 aec65d798..0622701f7 100644 --- a/src/display.c +++ b/src/display.c @@ -29,6 +29,7 @@ #include "keybindings.h" #include "workspace.h" #include +#include #include #define USE_GDK_DISPLAY @@ -554,6 +555,47 @@ event_queue_callback (XEvent *event, event_callback (event, data); } +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 11718ab49..c04d96540 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 d0ab9b212..5af3a1a6d 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; + MetaGrabOp op; - meta_core_get_size (gdk_display, - frame->xwindow, - &w, &h); - - 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); - } + 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_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); - } - 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 b53325eed..4531d2a44 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 f91c7d0a4..177b6d649 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 83d1c9f5d..7f704ed49 100644 --- a/src/screen.c +++ b/src/screen.c @@ -28,7 +28,6 @@ #include "keybindings.h" #include "stack.h" -#include #include #include #include @@ -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 c733d6358..ce0a4baa7 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 f50dfc423..c9c66b510 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 04d147b85..874fdfc6e 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 3136e060c..9e0dc7190 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 9bd3b8b9d..74217324d 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