[PATCH weston 3/6] xwm: set appropriate cursors for the frame window

Kristian Høgsberg hoegsberg at gmail.com
Wed Jul 11 19:39:40 PDT 2012


On Thu, Jul 12, 2012 at 12:46:12AM +0300, Tiago Vignatti wrote:
> based on xcb-cursor.

Looks good, but there's a couple of comments below.

Kristian

> Signed-off-by: Tiago Vignatti <tiago.vignatti at intel.com>
> ---
>  src/xwayland/window-manager.c |  132 +++++++++++++++++++++++++++++++++++++++++
>  src/xwayland/xwayland.h       |    2 +
>  2 files changed, 134 insertions(+)
> 
> diff --git a/src/xwayland/window-manager.c b/src/xwayland/window-manager.c
> index 6e032ea..0f2b24d 100644
> --- a/src/xwayland/window-manager.c
> +++ b/src/xwayland/window-manager.c
> @@ -497,6 +497,8 @@ weston_wm_handle_map_request(struct weston_wm *wm, xcb_generic_event_t *event)
>  		XCB_EVENT_MASK_KEY_RELEASE |
>  		XCB_EVENT_MASK_BUTTON_PRESS |
>  		XCB_EVENT_MASK_BUTTON_RELEASE |
> +		XCB_EVENT_MASK_POINTER_MOTION |
> +		XCB_EVENT_MASK_LEAVE_WINDOW |
>  		XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY |
>  		XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT;
>  
> @@ -852,6 +854,95 @@ weston_wm_handle_client_message(struct weston_wm *wm,
>  		weston_wm_window_handle_moveresize(window, client_message);
>  }
>  
> +enum cursor_type {
> +	XWM_CURSOR_TOP,
> +	XWM_CURSOR_BOTTOM,
> +	XWM_CURSOR_LEFT,
> +	XWM_CURSOR_RIGHT,
> +	XWM_CURSOR_TOP_LEFT,
> +	XWM_CURSOR_TOP_RIGHT,
> +	XWM_CURSOR_BOTTOM_LEFT,
> +	XWM_CURSOR_BOTTOM_RIGHT,
> +	XWM_CURSOR_LEFT_PTR,
> +};
> +
> +static const char *cursors[] = {
> +	"top_side",
> +	"bottom_side",
> +	"left_side",
> +	"right_side",
> +	"top_left_corner",
> +	"top_right_corner",
> +	"bottom_left_corner",
> +	"bottom_right_corner",
> +	"left_ptr"
> +};
> +
> +static void
> +weston_wm_create_cursors(struct weston_wm *wm)
> +{
> +	int i, count = ARRAY_LENGTH(cursors);
> +
> +	wm->cursors = malloc(count * sizeof(xcb_cursor_t));
> +	for (i = 0; i < count; i++) {
> +		wm->cursors[i] =
> +			xcb_cursor_library_load_cursor(wm->conn, cursors[i]);
> +	}
> +
> +	wm->last_cursor = -1;
> +}
> +
> +static int
> +get_cursor_for_location(struct theme *t, int width, int height,
> +			     int x, int y)
> +{
> +	int location = theme_get_location(t, x, y, width, height);
> +
> +	switch (location) {
> +		case THEME_LOCATION_RESIZING_TOP:
> +			return XWM_CURSOR_TOP;
> +		case THEME_LOCATION_RESIZING_BOTTOM:
> +			return XWM_CURSOR_BOTTOM;
> +		case THEME_LOCATION_RESIZING_LEFT:
> +			return XWM_CURSOR_LEFT;
> +		case THEME_LOCATION_RESIZING_RIGHT:
> +			return XWM_CURSOR_RIGHT;
> +		case THEME_LOCATION_RESIZING_TOP_LEFT:
> +			return XWM_CURSOR_TOP_LEFT;
> +		case THEME_LOCATION_RESIZING_TOP_RIGHT:
> +			return XWM_CURSOR_TOP_RIGHT;
> +		case THEME_LOCATION_RESIZING_BOTTOM_LEFT:
> +			return XWM_CURSOR_BOTTOM_LEFT;
> +		case THEME_LOCATION_RESIZING_BOTTOM_RIGHT:
> +			return XWM_CURSOR_BOTTOM_RIGHT;
> +		case THEME_LOCATION_EXTERIOR:
> +		case THEME_LOCATION_TITLEBAR:
> +		default:
> +			return XWM_CURSOR_LEFT_PTR;
> +	}
> +}
> +
> +static void
> +weston_wm_frame_set_cursor(struct weston_wm *wm,
> +			   struct weston_wm_window *window, int cursor)
> +{
> +	uint32_t cursor_value_list;
> +
> +	if (!window->frame_id)
> +		return;
> +
> +	if (wm->last_cursor == cursor)
> +		return;
> +
> +	wm->last_cursor = cursor;
> +
> +	cursor_value_list = wm->cursors[cursor];
> +	xcb_change_window_attributes (wm->conn, window->frame_id,
> +				      XCB_CW_CURSOR, &cursor_value_list);
> +	xcb_flush(wm->conn);
> +	weston_log("%s: %s\n", __func__, cursors[cursor]);
> +}
> +
>  static void
>  weston_wm_handle_button(struct weston_wm *wm, xcb_generic_event_t *event)
>  {
> @@ -900,6 +991,38 @@ weston_wm_handle_button(struct weston_wm *wm, xcb_generic_event_t *event)
>  	}
>  }
>  
> +static void
> +weston_wm_handle_motion(struct weston_wm *wm, xcb_generic_event_t *event)
> +{
> +	xcb_motion_notify_event_t *motion = (xcb_motion_notify_event_t *) event;
> +	struct weston_wm_window *window;
> +	int cursor, width, height;
> +
> +	window = hash_table_lookup(wm->window_hash, motion->event);
> +	if (!window->frame_id)
> +		return;
> +
> +	weston_wm_window_get_frame_size(window, &width, &height);
> +	cursor = get_cursor_for_location(wm->theme, width, height,
> +					 motion->event_x, motion->event_y);
> +
> +	weston_wm_frame_set_cursor(wm, window, cursor);
> +}
> +
> +static void
> +weston_wm_handle_leave(struct weston_wm *wm, xcb_generic_event_t *event)
> +{
> +	xcb_leave_notify_event_t *leave_notify =
> +				(xcb_leave_notify_event_t *) event;
> +	struct weston_wm_window *window;
> +
> +	window = hash_table_lookup(wm->window_hash, leave_notify->event);
> +	if (!window)
> +		return;
> +
> +	weston_wm_frame_set_cursor(wm, window, XWM_CURSOR_LEFT_PTR);
> +}

We don't need to set the cursor on leave, whatever window the cursor
moves into will set it.  But we do need to set it on enter.  I'd
suggest making weston_wm_frame_set_cursor take wm, window id, and x
and y.  We can look up the window and the cursor for the location
there.  Then both the motion and enter handlers can call this with the
window id and coordinates they receive.

>  static int
>  weston_wm_handle_event(int fd, uint32_t mask, void *data)
>  {
> @@ -919,6 +1042,12 @@ weston_wm_handle_event(int fd, uint32_t mask, void *data)
>  		case XCB_BUTTON_RELEASE:
>  			weston_wm_handle_button(wm, event);
>  			break;
> +		case XCB_LEAVE_NOTIFY:
> +			weston_wm_handle_leave(wm, event);
> +			break;
> +		case XCB_MOTION_NOTIFY:
> +			weston_wm_handle_motion(wm, event);
> +			break;
>  		case XCB_CREATE_NOTIFY:
>  			weston_wm_handle_create_notify(wm, event);
>  			break;
> @@ -1204,6 +1333,8 @@ weston_wm_create(struct weston_xserver *wxs)
>  	wl_signal_add(&wxs->compositor->activate_signal,
>  		      &wm->activate_listener);
>  
> +	weston_wm_create_cursors(wm);
> +
>  	weston_log("created wm\n");
>  
>  	return wm;
> @@ -1219,6 +1350,7 @@ weston_wm_destroy(struct weston_wm *wm)
>  	wl_list_remove(&wm->selection_listener.link);
>  	wl_list_remove(&wm->activate_listener.link);
>  
> +	free(wm->cursors);

We need to free the cursors too here.

>  	free(wm);
>  }
>  
> diff --git a/src/xwayland/xwayland.h b/src/xwayland/xwayland.h
> index 1a022d0..f9f4f93 100644
> --- a/src/xwayland/xwayland.h
> +++ b/src/xwayland/xwayland.h
> @@ -58,6 +58,8 @@ struct weston_wm {
>  	xcb_window_t wm_window;
>  	struct weston_wm_window *focus_window;
>  	struct theme *theme;
> +	xcb_cursor_t *cursors;
> +	int last_cursor;
>  	xcb_render_pictforminfo_t render_format;
>  	struct wl_listener activate_listener;
>  
> -- 
> 1.7.9.5
> 
> _______________________________________________
> wayland-devel mailing list
> wayland-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/wayland-devel


More information about the wayland-devel mailing list