diff --git a/src/core/core.c b/src/core/core.c index 0b0d1f67d..6c808765c 100644 --- a/src/core/core.c +++ b/src/core/core.c @@ -757,13 +757,24 @@ meta_core_grab_buttons (Display *xdisplay, } void -meta_core_set_screen_cursor (Display *xdisplay, - Window frame_on_screen, - MetaCursor cursor) +meta_core_set_screen_cursor (Display *xdisplay, + Window frame_on_screen, + gint device_id, + MetaCursor cursor) { MetaWindow *window = get_window (xdisplay, frame_on_screen); + MetaDevice *pointer; - meta_frame_set_screen_cursor (window->frame, cursor); + pointer = meta_device_map_lookup (window->display->device_map, + device_id); + + if (pointer == NULL) + return; + + if (!META_IS_DEVICE_POINTER (pointer)) + pointer = meta_device_get_paired_device (pointer); + + meta_frame_set_screen_cursor (window->frame, pointer, cursor); } void diff --git a/src/core/core.h b/src/core/core.h index 48171a701..28e753cd7 100644 --- a/src/core/core.h +++ b/src/core/core.h @@ -200,9 +200,10 @@ Window meta_core_get_frame (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); +void meta_core_set_screen_cursor (Display *xdisplay, + Window frame_on_screen, + int device_id, + MetaCursor cursor); void meta_core_select_events (Display *xdisplay, Window xwindow, diff --git a/src/core/frame.c b/src/core/frame.c index fe07768c8..aa54d48fd 100644 --- a/src/core/frame.c +++ b/src/core/frame.c @@ -28,6 +28,7 @@ #include "bell.h" #include #include "keybindings-private.h" +#include "device-pointer.h" #include @@ -64,7 +65,7 @@ meta_window_ensure_frame (MetaWindow *window) frame->child_y = 0; frame->bottom_height = 0; frame->right_width = 0; - frame->current_cursor = 0; + frame->cursors = g_hash_table_new (NULL, NULL); frame->mapped = FALSE; frame->is_flashing = FALSE; @@ -228,9 +229,10 @@ meta_window_destroy_frame (MetaWindow *window) /* Move keybindings to window instead of frame */ meta_window_grab_keys (window); - + + g_hash_table_destroy (frame->cursors); g_free (frame); - + /* Put our state back where it should be */ meta_window_queue (window, META_QUEUE_CALC_SHOWING); meta_window_queue (window, META_QUEUE_MOVE_RESIZE); @@ -402,22 +404,22 @@ meta_frame_queue_draw (MetaFrame *frame) } void -meta_frame_set_screen_cursor (MetaFrame *frame, - MetaCursor cursor) +meta_frame_set_screen_cursor (MetaFrame *frame, + MetaDevice *pointer, + MetaCursor cursor) { - Cursor xcursor; - if (cursor == frame->current_cursor) + MetaCursor old_cursor; + + old_cursor = GPOINTER_TO_UINT (g_hash_table_lookup (frame->cursors, pointer)); + + if (cursor == old_cursor) return; - frame->current_cursor = cursor; - if (cursor == META_CURSOR_DEFAULT) - XUndefineCursor (frame->window->display->xdisplay, frame->xwindow); - else - { - xcursor = meta_display_create_x_cursor (frame->window->display, cursor); - XDefineCursor (frame->window->display->xdisplay, frame->xwindow, xcursor); - XFlush (frame->window->display->xdisplay); - XFreeCursor (frame->window->display->xdisplay, xcursor); - } + + g_hash_table_insert (frame->cursors, pointer, + GUINT_TO_POINTER (cursor)); + meta_device_pointer_set_window_cursor (META_DEVICE_POINTER (pointer), + frame->xwindow, cursor); + XFlush (frame->window->display->xdisplay); } Window diff --git a/src/core/frame.h b/src/core/frame.h index d612f7779..78ae3d188 100644 --- a/src/core/frame.h +++ b/src/core/frame.h @@ -34,7 +34,7 @@ struct _MetaFrame /* reparent window */ Window xwindow; - MetaCursor current_cursor; + GHashTable *cursors; /* This rect is trusted info from where we put the * frame, not the result of ConfigureNotify @@ -76,7 +76,8 @@ gboolean meta_frame_sync_to_window (MetaFrame *frame, cairo_region_t *meta_frame_get_frame_bounds (MetaFrame *frame); -void meta_frame_set_screen_cursor (MetaFrame *frame, +void meta_frame_set_screen_cursor (MetaFrame *frame, + MetaDevice *pointer, MetaCursor cursor); #endif diff --git a/src/ui/frames.c b/src/ui/frames.c index bbac9e3d3..66bd38ef7 100644 --- a/src/ui/frames.c +++ b/src/ui/frames.c @@ -734,10 +734,18 @@ meta_frames_unmanage_window (MetaFrames *frames, */ invalidate_all_caches (frames); +#if 0 + /* This function is only called when destroying the frame + * in core/frame.c, ideally this should be done for every + * device with a cursor on the frame, but in practical + * effects it doesn't matter. + */ + /* restore the cursor */ meta_core_set_screen_cursor (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), frame->xwindow, META_CURSOR_DEFAULT); +#endif gdk_window_set_user_data (frame->window, NULL); @@ -1848,8 +1856,10 @@ meta_frames_update_prelit_control (MetaFrames *frames, MetaFrameControl control) { MetaFrameControl old_control; + GdkDevice *device; MetaCursor cursor; + device = gtk_get_current_event_device (); meta_verbose ("Updating prelit control from %u to %u\n", frame->prelit_control, control); @@ -1915,6 +1925,7 @@ meta_frames_update_prelit_control (MetaFrames *frames, /* set/unset the prelight cursor */ meta_core_set_screen_cursor (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), frame->xwindow, + gdk_x11_device_get_id (device), cursor); switch (control)