diff options
| -rw-r--r-- | backend/drm/drm.c | 43 | ||||
| -rw-r--r-- | backend/libinput/keyboard.c | 3 | ||||
| -rw-r--r-- | backend/wayland/output.c | 11 | ||||
| -rw-r--r-- | backend/wayland/wl_seat.c | 9 | ||||
| -rw-r--r-- | backend/x11/backend.c | 4 | ||||
| -rw-r--r-- | examples/pointer.c | 3 | ||||
| -rw-r--r-- | include/backend/wayland.h | 3 | ||||
| -rw-r--r-- | include/rootston/input.h | 2 | ||||
| -rw-r--r-- | include/rootston/view.h | 2 | ||||
| -rw-r--r-- | include/wlr/interfaces/wlr_keyboard.h | 5 | ||||
| -rw-r--r-- | include/wlr/interfaces/wlr_output.h | 3 | ||||
| -rw-r--r-- | include/wlr/types/wlr_keyboard.h | 1 | ||||
| -rw-r--r-- | include/wlr/types/wlr_output.h | 4 | ||||
| -rw-r--r-- | include/wlr/types/wlr_xdg_shell_v6.h | 5 | ||||
| -rw-r--r-- | rootston/cursor.c | 6 | ||||
| -rw-r--r-- | rootston/desktop.c | 16 | ||||
| -rw-r--r-- | rootston/keyboard.c | 15 | ||||
| -rw-r--r-- | rootston/output.c | 3 | ||||
| -rw-r--r-- | rootston/rootston.ini.example | 5 | ||||
| -rw-r--r-- | rootston/wl_shell.c | 7 | ||||
| -rw-r--r-- | rootston/xdg_shell_v6.c | 9 | ||||
| -rw-r--r-- | rootston/xwayland.c | 21 | ||||
| -rw-r--r-- | types/wlr_cursor.c | 14 | ||||
| -rw-r--r-- | types/wlr_keyboard.c | 18 | ||||
| -rw-r--r-- | types/wlr_output.c | 20 | ||||
| -rw-r--r-- | types/wlr_xdg_shell_v6.c | 5 | ||||
| -rw-r--r-- | xwayland/xwm.c | 33 | 
27 files changed, 204 insertions, 66 deletions
| diff --git a/backend/drm/drm.c b/backend/drm/drm.c index fc376b54..9e5346a1 100644 --- a/backend/drm/drm.c +++ b/backend/drm/drm.c @@ -469,7 +469,8 @@ static void wlr_drm_connector_transform(struct wlr_output *output,  }  static bool wlr_drm_connector_set_cursor(struct wlr_output *output, -		const uint8_t *buf, int32_t stride, uint32_t width, uint32_t height) { +		const uint8_t *buf, int32_t stride, uint32_t width, uint32_t height, +		int32_t hotspot_x, int32_t hotspot_y) {  	struct wlr_drm_connector *conn = (struct wlr_drm_connector *)output;  	struct wlr_drm_backend *drm = conn->drm;  	struct wlr_drm_renderer *renderer = &drm->renderer; @@ -534,6 +535,37 @@ static bool wlr_drm_connector_set_cursor(struct wlr_output *output,  		}  	} +	switch (output->transform) { +	case WL_OUTPUT_TRANSFORM_90: +		output->cursor.hotspot_x = hotspot_x; +		output->cursor.hotspot_y = -plane->surf.height + hotspot_y; +		break; +	case WL_OUTPUT_TRANSFORM_180: +		output->cursor.hotspot_x = plane->surf.width - hotspot_x; +		output->cursor.hotspot_y = plane->surf.height - hotspot_y; +		break; +	case WL_OUTPUT_TRANSFORM_270: +		output->cursor.hotspot_x = -plane->surf.height + hotspot_x; +		output->cursor.hotspot_y = hotspot_y; +		break; +	case WL_OUTPUT_TRANSFORM_FLIPPED: +		output->cursor.hotspot_x = plane->surf.width - hotspot_x; +		output->cursor.hotspot_y = hotspot_y; +		break; +	case WL_OUTPUT_TRANSFORM_FLIPPED_90: +		output->cursor.hotspot_x = hotspot_x; +		output->cursor.hotspot_y = -hotspot_y; +		break; +	case WL_OUTPUT_TRANSFORM_FLIPPED_180: +		output->cursor.hotspot_x = hotspot_x; +		output->cursor.hotspot_y = plane->surf.height - hotspot_y; +		break; +	case WL_OUTPUT_TRANSFORM_FLIPPED_270: +		output->cursor.hotspot_x = -plane->surf.height + hotspot_x; +		output->cursor.hotspot_y = plane->surf.width - hotspot_y; +		break; +	} +  	struct gbm_bo *bo = plane->cursor_bo;  	uint32_t bo_width = gbm_bo_get_width(bo);  	uint32_t bo_height = gbm_bo_get_height(bo); @@ -581,23 +613,22 @@ static bool wlr_drm_connector_move_cursor(struct wlr_output *output,  	switch (output->transform) {  	case WL_OUTPUT_TRANSFORM_NORMAL: +	case WL_OUTPUT_TRANSFORM_FLIPPED: +	case WL_OUTPUT_TRANSFORM_FLIPPED_180:  		// nothing to do  		break;  	case WL_OUTPUT_TRANSFORM_270: +	case WL_OUTPUT_TRANSFORM_FLIPPED_270:  		tmp = x;  		x = y;  		y = -(tmp - width);  		break;  	case WL_OUTPUT_TRANSFORM_90: +	case WL_OUTPUT_TRANSFORM_FLIPPED_90:  		tmp = x;  		x = -(y - height);  		y = tmp;  		break; -	default: -		// TODO other transformations -		wlr_log(L_ERROR, "TODO: handle surface to crtc for transformation = %d", -			output->transform); -		break;  	}  	return drm->iface->crtc_move_cursor(drm, conn->crtc, x, y); diff --git a/backend/libinput/keyboard.c b/backend/libinput/keyboard.c index 53c3a61b..00a7ecdf 100644 --- a/backend/libinput/keyboard.c +++ b/backend/libinput/keyboard.c @@ -67,5 +67,6 @@ void handle_keyboard_key(struct libinput_event *event,  		wlr_event.state = WLR_KEY_PRESSED;  		break;  	} -	wlr_keyboard_update_state(wlr_dev->keyboard, &wlr_event); +	wlr_event.update_state = true; +	wlr_keyboard_notify_key(wlr_dev->keyboard, &wlr_event);  } diff --git a/backend/wayland/output.c b/backend/wayland/output.c index ba04aede..062a91a1 100644 --- a/backend/wayland/output.c +++ b/backend/wayland/output.c @@ -53,7 +53,8 @@ static void wlr_wl_output_transform(struct wlr_output *_output,  }  static bool wlr_wl_output_set_cursor(struct wlr_output *_output, -		const uint8_t *buf, int32_t stride, uint32_t width, uint32_t height) { +		const uint8_t *buf, int32_t stride, uint32_t width, uint32_t height, +		int32_t hotspot_x, int32_t hotspot_y) {  	struct wlr_wl_backend_output *output = (struct wlr_wl_backend_output *)_output;  	struct wlr_wl_backend *backend = output->backend; @@ -110,7 +111,8 @@ static bool wlr_wl_output_set_cursor(struct wlr_output *_output,  	wl_surface_damage(output->cursor_surface, 0, 0, width, height);  	wl_surface_commit(output->cursor_surface); -	wlr_wl_output_update_cursor(output, output->enter_serial); +	wlr_wl_output_update_cursor(output, output->enter_serial, +		hotspot_x, hotspot_y);  	return true;  } @@ -143,10 +145,11 @@ static void wlr_wl_output_destroy(struct wlr_output *_output) {  	free(output);  } -void wlr_wl_output_update_cursor(struct wlr_wl_backend_output *output, uint32_t serial) { +void wlr_wl_output_update_cursor(struct wlr_wl_backend_output *output, +			uint32_t serial, int32_t hotspot_x, int32_t hotspot_y) {  	if (output->cursor_surface && output->backend->pointer && serial) {  		wl_pointer_set_cursor(output->backend->pointer, serial, -			output->cursor_surface, 0, 0); +			output->cursor_surface, hotspot_x, hotspot_y);  	}  } diff --git a/backend/wayland/wl_seat.c b/backend/wayland/wl_seat.c index ba3feb8d..d3ff9b64 100644 --- a/backend/wayland/wl_seat.c +++ b/backend/wayland/wl_seat.c @@ -24,7 +24,7 @@ static void pointer_handle_enter(void *data, struct wl_pointer *wl_pointer,  	assert(output);  	wlr_wl_pointer->current_output = output;  	wlr_wl_pointer->current_output->enter_serial = serial; -	wlr_wl_output_update_cursor(wlr_wl_pointer->current_output, serial); +	wlr_wl_output_update_cursor(wlr_wl_pointer->current_output, serial, 0, 0);  }  static void pointer_handle_leave(void *data, struct wl_pointer *wl_pointer, @@ -149,13 +149,16 @@ static void keyboard_handle_key(void *data, struct wl_keyboard *wl_keyboard,  	wlr_event.state = state;  	wlr_event.time_sec = time / 1000;  	wlr_event.time_usec = time * 1000; -	wlr_keyboard_update_state(dev->keyboard, &wlr_event); +	wlr_keyboard_notify_key(dev->keyboard, &wlr_event);  }  static void keyboard_handle_modifiers(void *data, struct wl_keyboard *wl_keyboard,  		uint32_t serial, uint32_t mods_depressed, uint32_t mods_latched,  		uint32_t mods_locked, uint32_t group) { - +	struct wlr_input_device *dev = data; +	assert(dev && dev->keyboard); +	wlr_keyboard_notify_modifiers(dev->keyboard, mods_depressed, mods_latched, +		mods_locked, group);  }  static void keyboard_handle_repeat_info(void *data, struct wl_keyboard *wl_keyboard, diff --git a/backend/x11/backend.c b/backend/x11/backend.c index e0f57f82..2134536c 100644 --- a/backend/x11/backend.c +++ b/backend/x11/backend.c @@ -51,9 +51,11 @@ static bool handle_x11_event(struct wlr_x11_backend *x11, xcb_generic_event_t *e  			.keycode = ev->detail - 8,  			.state = event->response_type == XCB_KEY_PRESS ?  				WLR_KEY_PRESSED : WLR_KEY_RELEASED, +			.update_state = true,  		}; -		wl_signal_emit(&x11->keyboard.events.key, &key); +		// TODO use xcb-xkb for more precise modifiers state? +		wlr_keyboard_notify_key(&x11->keyboard, &key);  		x11->time = ev->time;  		break;  	} diff --git a/examples/pointer.c b/examples/pointer.c index 11f67f9b..238be9b3 100644 --- a/examples/pointer.c +++ b/examples/pointer.c @@ -112,7 +112,8 @@ static void handle_output_add(struct output_state *ostate) {  	// TODO the cursor must be set depending on which surface it is displayed  	// over which should happen in the compositor.  	if (!wlr_output_set_cursor(wlr_output, image->buffer, -			image->width, image->width, image->height)) { +			image->width, image->width, image->height, +			image->hotspot_x, image->hotspot_y)) {  		wlr_log(L_DEBUG, "Failed to set hardware cursor");  		return;  	} diff --git a/include/backend/wayland.h b/include/backend/wayland.h index 752dab69..508a7f52 100644 --- a/include/backend/wayland.h +++ b/include/backend/wayland.h @@ -67,7 +67,8 @@ struct wlr_wl_pointer {  };  void wlr_wl_registry_poll(struct wlr_wl_backend *backend); -void wlr_wl_output_update_cursor(struct wlr_wl_backend_output *output, uint32_t serial); +void wlr_wl_output_update_cursor(struct wlr_wl_backend_output *output, +		uint32_t serial, int32_t hotspot_x, int32_t hotspot_y);  struct wlr_wl_backend_output *wlr_wl_output_for_surface(  		struct wlr_wl_backend *backend, struct wl_surface *surface); diff --git a/include/rootston/input.h b/include/rootston/input.h index 4b9bd1dd..e20446ea 100644 --- a/include/rootston/input.h +++ b/include/rootston/input.h @@ -81,7 +81,7 @@ struct roots_input {  	struct wlr_seat *wl_seat;  	enum roots_cursor_mode mode; -	struct roots_view *active_view; +	struct roots_view *active_view, *last_active_view;  	int offs_x, offs_y;  	int view_x, view_y, view_width, view_height;  	float view_rotation; diff --git a/include/rootston/view.h b/include/rootston/view.h index 39ff80db..64aad45e 100644 --- a/include/rootston/view.h +++ b/include/rootston/view.h @@ -65,11 +65,13 @@ struct roots_view {  	void (*get_input_bounds)(struct roots_view *view, struct wlr_box *box);  	void (*activate)(struct roots_view *view, bool active);  	void (*resize)(struct roots_view *view, uint32_t width, uint32_t height); +	void (*close)(struct roots_view *view);  };  void view_get_size(struct roots_view *view, struct wlr_box *box);  void view_get_input_bounds(struct roots_view *view, struct wlr_box *box);  void view_activate(struct roots_view *view, bool active);  void view_resize(struct roots_view *view, uint32_t width, uint32_t height); +void view_close(struct roots_view *view);  #endif diff --git a/include/wlr/interfaces/wlr_keyboard.h b/include/wlr/interfaces/wlr_keyboard.h index 78c1f753..570f5721 100644 --- a/include/wlr/interfaces/wlr_keyboard.h +++ b/include/wlr/interfaces/wlr_keyboard.h @@ -11,7 +11,10 @@ struct wlr_keyboard_impl {  void wlr_keyboard_init(struct wlr_keyboard *keyboard, struct wlr_keyboard_impl *impl);  void wlr_keyboard_destroy(struct wlr_keyboard *keyboard); -void wlr_keyboard_update_state(struct wlr_keyboard *keyboard, +void wlr_keyboard_notify_key(struct wlr_keyboard *keyboard,  		struct wlr_event_keyboard_key *event); +void wlr_keyboard_notify_modifiers(struct wlr_keyboard *keyboard, +		uint32_t mods_depressed, uint32_t mods_latched, uint32_t mods_locked, +		uint32_t group);  #endif diff --git a/include/wlr/interfaces/wlr_output.h b/include/wlr/interfaces/wlr_output.h index 7ed19ed9..7d2821e0 100644 --- a/include/wlr/interfaces/wlr_output.h +++ b/include/wlr/interfaces/wlr_output.h @@ -10,7 +10,8 @@ struct wlr_output_impl {  	void (*transform)(struct wlr_output *output,  			enum wl_output_transform transform);  	bool (*set_cursor)(struct wlr_output *output, const uint8_t *buf, -			int32_t stride, uint32_t width, uint32_t height); +			int32_t stride, uint32_t width, uint32_t height, +			int32_t hotspot_x, int32_t hotspot_y);  	bool (*move_cursor)(struct wlr_output *output, int x, int y);  	void (*destroy)(struct wlr_output *output);  	void (*make_current)(struct wlr_output *output); diff --git a/include/wlr/types/wlr_keyboard.h b/include/wlr/types/wlr_keyboard.h index 9ec8ddd4..99a624c2 100644 --- a/include/wlr/types/wlr_keyboard.h +++ b/include/wlr/types/wlr_keyboard.h @@ -65,6 +65,7 @@ struct wlr_event_keyboard_key {  	uint32_t time_sec;  	uint64_t time_usec;  	uint32_t keycode; +	bool update_state;  	enum wlr_key_state state;  }; diff --git a/include/wlr/types/wlr_output.h b/include/wlr/types/wlr_output.h index 3208acac..1fa6ad9e 100644 --- a/include/wlr/types/wlr_output.h +++ b/include/wlr/types/wlr_output.h @@ -45,6 +45,7 @@ struct wlr_output {  		bool is_sw;  		int32_t x, y;  		uint32_t width, height; +		int32_t hotspot_x, hotspot_y;  		struct wlr_renderer *renderer;  		struct wlr_texture *texture;  	} cursor; @@ -58,7 +59,8 @@ bool wlr_output_set_mode(struct wlr_output *output,  void wlr_output_transform(struct wlr_output *output,  		enum wl_output_transform transform);  bool wlr_output_set_cursor(struct wlr_output *output, -		const uint8_t *buf, int32_t stride, uint32_t width, uint32_t height); +		const uint8_t *buf, int32_t stride, uint32_t width, uint32_t height, +		int32_t hotspot_x, int32_t hotspot_y);  bool wlr_output_move_cursor(struct wlr_output *output, int x, int y);  void wlr_output_destroy(struct wlr_output *output);  void wlr_output_effective_resolution(struct wlr_output *output, diff --git a/include/wlr/types/wlr_xdg_shell_v6.h b/include/wlr/types/wlr_xdg_shell_v6.h index 0a633822..00295ec1 100644 --- a/include/wlr/types/wlr_xdg_shell_v6.h +++ b/include/wlr/types/wlr_xdg_shell_v6.h @@ -201,4 +201,9 @@ void wlr_xdg_toplevel_v6_set_fullscreen(struct wlr_xdg_surface_v6 *surface,  void wlr_xdg_toplevel_v6_set_resizing(struct wlr_xdg_surface_v6 *surface,  		bool resizing); +/** + * Request that this toplevel surface closes. + */ +void wlr_xdg_toplevel_v6_send_close(struct wlr_xdg_surface_v6 *surface); +  #endif diff --git a/rootston/cursor.c b/rootston/cursor.c index 2918b50f..8eb22459 100644 --- a/rootston/cursor.c +++ b/rootston/cursor.c @@ -133,15 +133,19 @@ static void set_view_focus(struct roots_input *input,  	if (!view) {  		return;  	} +	input->last_active_view = view;  	size_t index = 0;  	for (size_t i = 0; i < desktop->views->length; ++i) {  		struct roots_view *_view = desktop->views->items[i]; -		view_activate(_view, _view == view); +		if (_view != view) { +			view_activate(_view, false); +		}  		if (view == _view) {  			index = i;  		}  	} +	view_activate(view, true);  	// TODO: list_swap  	list_del(desktop->views, index);  	list_add(desktop->views, view); diff --git a/rootston/desktop.c b/rootston/desktop.c index d5a61f2a..6653a16b 100644 --- a/rootston/desktop.c +++ b/rootston/desktop.c @@ -16,6 +16,16 @@  void view_destroy(struct roots_view *view) {  	struct roots_desktop *desktop = view->desktop; + +	struct roots_input *input = desktop->server->input; +	if (input->active_view == view) { +		input->active_view = NULL; +		input->mode = ROOTS_CURSOR_PASSTHROUGH; +	} +	if (input->last_active_view == view) { +		input->last_active_view = NULL; +	} +  	for (size_t i = 0; i < desktop->views->length; ++i) {  		struct roots_view *_view = desktop->views->items[i];  		if (view == _view) { @@ -67,6 +77,12 @@ void view_resize(struct roots_view *view, uint32_t width, uint32_t height) {  	}  } +void view_close(struct roots_view *view) { +	if (view->close) { +		view->close(view); +	} +} +  static struct wlr_subsurface *subsurface_at(struct wlr_surface *surface,  		double sx, double sy, double *sub_x, double *sub_y) {  	struct wlr_subsurface *subsurface; diff --git a/rootston/keyboard.c b/rootston/keyboard.c index 6f6fa0e8..6f4334af 100644 --- a/rootston/keyboard.c +++ b/rootston/keyboard.c @@ -21,19 +21,28 @@ static ssize_t keyboard_pressed_keysym_index(struct roots_keyboard *keyboard,  	return -1;  } +static const char *exec_prefix = "exec "; +  static void keyboard_binding_execute(struct roots_keyboard *keyboard, -		char *command) { +		const char *command) {  	struct roots_server *server = keyboard->input->server;  	if (strcmp(command, "exit") == 0) {  		wl_display_terminate(server->wl_display); -	} else { +	} else if (strcmp(command, "close") == 0) { +		if (keyboard->input->last_active_view != NULL) { +			view_close(keyboard->input->last_active_view); +		} +	} else if (strncmp(exec_prefix, command, strlen(exec_prefix)) == 0) { +		const char *shell_cmd = command + strlen(exec_prefix);  		pid_t pid = fork();  		if (pid < 0) {  			wlr_log(L_ERROR, "cannot execute binding command: fork() failed");  			return;  		} else if (pid == 0) { -			execl("/bin/sh", "/bin/sh", "-c", command, (void *)NULL); +			execl("/bin/sh", "/bin/sh", "-c", shell_cmd, (void *)NULL);  		} +	} else { +		wlr_log(L_ERROR, "unknown binding command: %s", command);  	}  } diff --git a/rootston/output.c b/rootston/output.c index 32923042..6c7fbf51 100644 --- a/rootston/output.c +++ b/rootston/output.c @@ -169,7 +169,8 @@ void output_add_notify(struct wl_listener *listener, void *data) {  	// TODO the cursor must be set depending on which surface it is displayed  	// over which should happen in the compositor.  	if (!wlr_output_set_cursor(wlr_output, image->buffer, -			image->width, image->width, image->height)) { +			image->width, image->width, image->height, +			image->hotspot_x, image->hotspot_y)) {  		wlr_log(L_DEBUG, "Failed to set hardware cursor");  		return;  	} diff --git a/rootston/rootston.ini.example b/rootston/rootston.ini.example index 9960cae1..8ac474d4 100644 --- a/rootston/rootston.ini.example +++ b/rootston/rootston.ini.example @@ -30,6 +30,7 @@ meta-key = Logo  # Keybindings  # Maps key combinations with commands to execute -# The special command "exit" stops the compositor +# Use the prefix "exec" to execute a shell command  [bindings] -Logo+q = exit +Logo+Shift+e = exit # Stop the compositor +Logo+q = close # Close the current view diff --git a/rootston/wl_shell.c b/rootston/wl_shell.c index 1991d332..55ffd2eb 100644 --- a/rootston/wl_shell.c +++ b/rootston/wl_shell.c @@ -17,6 +17,12 @@ static void resize(struct roots_view *view, uint32_t width, uint32_t height) {  		height);  } +static void close(struct roots_view *view) { +	assert(view->type == ROOTS_WL_SHELL_VIEW); +	struct wlr_wl_shell_surface *surf = view->wl_shell_surface; +	wl_client_destroy(surf->client); +} +  static void handle_request_move(struct wl_listener *listener, void *data) {  	struct roots_wl_shell_surface *roots_surface =  		wl_container_of(listener, roots_surface, request_move); @@ -88,6 +94,7 @@ void handle_wl_shell_surface(struct wl_listener *listener, void *data) {  	view->roots_wl_shell_surface = roots_surface;  	view->wlr_surface = surface->surface;  	view->resize = resize; +	view->close = close;  	view->desktop = desktop;  	roots_surface->view = view;  	list_add(desktop->views, view); diff --git a/rootston/xdg_shell_v6.c b/rootston/xdg_shell_v6.c index ff0dd090..c0124d60 100644 --- a/rootston/xdg_shell_v6.c +++ b/rootston/xdg_shell_v6.c @@ -33,6 +33,14 @@ static void resize(struct roots_view *view, uint32_t width, uint32_t height) {  	}  } +static void close(struct roots_view *view) { +	assert(view->type == ROOTS_XDG_SHELL_V6_VIEW); +	struct wlr_xdg_surface_v6 *surf = view->xdg_surface_v6; +	if (surf->role == WLR_XDG_SURFACE_V6_ROLE_TOPLEVEL) { +		wlr_xdg_toplevel_v6_send_close(surf); +	} +} +  static void handle_request_move(struct wl_listener *listener, void *data) {  	struct roots_xdg_surface_v6 *roots_xdg_surface =  		wl_container_of(listener, roots_xdg_surface, request_move); @@ -114,6 +122,7 @@ void handle_xdg_shell_v6_surface(struct wl_listener *listener, void *data) {  	view->get_size = get_size;  	view->activate = activate;  	view->resize = resize; +	view->close = close;  	view->desktop = desktop;  	roots_surface->view = view;  	list_add(desktop->views, view); diff --git a/rootston/xwayland.c b/rootston/xwayland.c index 7ecc4d4f..c32ee15b 100644 --- a/rootston/xwayland.c +++ b/rootston/xwayland.c @@ -9,6 +9,16 @@  #include "rootston/desktop.h"  #include "rootston/server.h" +static void activate(struct roots_view *view, bool active) { +	assert(view->type == ROOTS_XWAYLAND_VIEW); +	if (active) { +		wlr_xwayland_surface_activate(view->desktop->xwayland, +			view->xwayland_surface); +	} else { +		wlr_xwayland_surface_activate(view->desktop->xwayland, NULL); +	} +} +  static void resize(struct roots_view *view, uint32_t width, uint32_t height) {  	assert(view->type == ROOTS_XWAYLAND_VIEW);  	struct wlr_xwayland_surface *xwayland_surface = view->xwayland_surface; @@ -16,6 +26,11 @@ static void resize(struct roots_view *view, uint32_t width, uint32_t height) {  		xwayland_surface->x, xwayland_surface->y, width, height);  } +static void close(struct roots_view *view) { +	assert(view->type == ROOTS_XWAYLAND_VIEW); +	wlr_xwayland_surface_close(view->desktop->xwayland, view->xwayland_surface); +} +  static void handle_destroy(struct wl_listener *listener, void *data) {  	struct roots_xwayland_surface *roots_surface =  		wl_container_of(listener, roots_surface, destroy); @@ -38,11 +53,6 @@ static void handle_request_configure(struct wl_listener *listener, void *data) {  		xwayland_surface, event->x, event->y, event->width, event->height);  } -static void activate(struct roots_view *view, bool active) { -	wlr_xwayland_surface_activate(view->desktop->xwayland, -		view->xwayland_surface); -} -  void handle_xwayland_surface(struct wl_listener *listener, void *data) {  	struct roots_desktop *desktop =  		wl_container_of(listener, desktop, xwayland_surface); @@ -78,6 +88,7 @@ void handle_xwayland_surface(struct wl_listener *listener, void *data) {  	view->desktop = desktop;  	view->activate = activate;  	view->resize = resize; +	view->close = close;  	roots_surface->view = view;  	list_add(desktop->views, view);  } diff --git a/types/wlr_cursor.c b/types/wlr_cursor.c index 79972745..20781f0a 100644 --- a/types/wlr_cursor.c +++ b/types/wlr_cursor.c @@ -131,15 +131,6 @@ static struct wlr_cursor_device *get_cursor_device(struct wlr_cursor *cur,  static void wlr_cursor_warp_unchecked(struct wlr_cursor *cur,  		double x, double y) {  	assert(cur->state->layout); -	int hotspot_x = 0; -	int hotspot_y = 0; - -	if (cur->state->xcursor && cur->state->xcursor->image_count > 0) { -		struct wlr_xcursor_image *image = cur->state->xcursor->images[0]; -		hotspot_x = image->hotspot_x; -		hotspot_y = image->hotspot_y; -	} -  	struct wlr_output_layout_output *l_output;  	wl_list_for_each(l_output, &cur->state->layout->outputs, link) { @@ -148,8 +139,9 @@ static void wlr_cursor_warp_unchecked(struct wlr_cursor *cur,  		wlr_output_layout_output_coords(cur->state->layout,  			l_output->output, &output_x, &output_y); -		wlr_output_move_cursor(l_output->output, output_x - hotspot_x, -			output_y - hotspot_y); +		wlr_output_move_cursor(l_output->output, +			output_x - l_output->output->cursor.hotspot_x, +			output_y - l_output->output->cursor.hotspot_y);  	}  	cur->x = x; diff --git a/types/wlr_keyboard.c b/types/wlr_keyboard.c index 5dbcf064..f37895b0 100644 --- a/types/wlr_keyboard.c +++ b/types/wlr_keyboard.c @@ -45,11 +45,21 @@ static void keyboard_modifier_update(struct wlr_keyboard *keyboard) {  	wl_signal_emit(&keyboard->events.modifiers, keyboard);  } -void wlr_keyboard_update_state(struct wlr_keyboard *keyboard, +void wlr_keyboard_notify_modifiers(struct wlr_keyboard *keyboard, +		uint32_t mods_depressed, uint32_t mods_latched, uint32_t mods_locked, +		uint32_t group) { +	xkb_state_update_mask(keyboard->xkb_state, mods_depressed, mods_latched, +		mods_locked, 0, 0, group); +	keyboard_modifier_update(keyboard); +} + +void wlr_keyboard_notify_key(struct wlr_keyboard *keyboard,  		struct wlr_event_keyboard_key *event) { -	uint32_t keycode = event->keycode + 8; -	xkb_state_update_key(keyboard->xkb_state, keycode, -		event->state == WLR_KEY_PRESSED ? XKB_KEY_DOWN : XKB_KEY_UP); +	if (event->update_state) { +		uint32_t keycode = event->keycode + 8; +		xkb_state_update_key(keyboard->xkb_state, keycode, +			event->state == WLR_KEY_PRESSED ? XKB_KEY_DOWN : XKB_KEY_UP); +	}  	keyboard_led_update(keyboard);  	keyboard_modifier_update(keyboard);  	wl_signal_emit(&keyboard->events.key, event); diff --git a/types/wlr_output.c b/types/wlr_output.c index 962685b8..f167a213 100644 --- a/types/wlr_output.c +++ b/types/wlr_output.c @@ -19,8 +19,8 @@ static void wl_output_send_to_resource(struct wl_resource *resource) {  	const uint32_t version = wl_resource_get_version(resource);  	if (version >= WL_OUTPUT_GEOMETRY_SINCE_VERSION) {  		wl_output_send_geometry(resource, 0, 0, // TODO: get position from layout? -				output->phys_width, output->phys_height, output->subpixel, -				output->make, output->model, output->transform); +			output->phys_width, output->phys_height, output->subpixel, +			output->make, output->model, output->transform);  	}  	if (version >= WL_OUTPUT_MODE_SINCE_VERSION) {  		for (size_t i = 0; i < output->modes->length; ++i) { @@ -31,7 +31,13 @@ static void wl_output_send_to_resource(struct wl_resource *resource) {  				flags |= WL_OUTPUT_MODE_CURRENT;  			}  			wl_output_send_mode(resource, flags, -					mode->width, mode->height, mode->refresh); +				mode->width, mode->height, mode->refresh); +		} + +		if (output->modes->length == 0) { +			// Output has no mode, send the current width/height +			wl_output_send_mode(resource, WL_OUTPUT_MODE_CURRENT, +				output->width, output->height, 0);  		}  	}  	if (version >= WL_OUTPUT_SCALE_SINCE_VERSION) { @@ -125,9 +131,11 @@ void wlr_output_transform(struct wlr_output *output,  }  bool wlr_output_set_cursor(struct wlr_output *output, -		const uint8_t *buf, int32_t stride, uint32_t width, uint32_t height) { +		const uint8_t *buf, int32_t stride, uint32_t width, uint32_t height, +		int32_t hotspot_x, int32_t hotspot_y) {  	if (output->impl->set_cursor -			&& output->impl->set_cursor(output, buf, stride, width, height)) { +			&& output->impl->set_cursor(output, buf, stride, width, height, +				hotspot_x, hotspot_y)) {  		output->cursor.is_sw = false;  		return true;  	} @@ -137,6 +145,8 @@ bool wlr_output_set_cursor(struct wlr_output *output,  	output->cursor.is_sw = true;  	output->cursor.width = width;  	output->cursor.height = height; +	output->cursor.hotspot_x = hotspot_x; +	output->cursor.hotspot_y = hotspot_y;  	if (!output->cursor.renderer) {  		/* NULL egl is okay given that we are only using pixel buffers */ diff --git a/types/wlr_xdg_shell_v6.c b/types/wlr_xdg_shell_v6.c index fe9a5359..fbe01528 100644 --- a/types/wlr_xdg_shell_v6.c +++ b/types/wlr_xdg_shell_v6.c @@ -1296,3 +1296,8 @@ void wlr_xdg_toplevel_v6_set_resizing(struct wlr_xdg_surface_v6 *surface,  	wlr_xdg_surface_v6_schedule_configure(surface, false);  } + +void wlr_xdg_toplevel_v6_send_close(struct wlr_xdg_surface_v6 *surface) { +	assert(surface->role == WLR_XDG_SURFACE_V6_ROLE_TOPLEVEL); +	zxdg_toplevel_v6_send_close(surface->toplevel_state->resource); +} diff --git a/xwayland/xwm.c b/xwayland/xwm.c index a4091d1f..bc1bb4de 100644 --- a/xwayland/xwm.c +++ b/xwayland/xwm.c @@ -705,19 +705,25 @@ static void xcb_init_wm(struct wlr_xwm *xwm) {  void wlr_xwayland_surface_activate(struct wlr_xwayland *wlr_xwayland,  		struct wlr_xwayland_surface *surface) {  	struct wlr_xwm *xwm = wlr_xwayland->xwm; -	xcb_client_message_event_t m = {0}; -	m.response_type = XCB_CLIENT_MESSAGE; -	m.format = 32; -	m.window = surface->window_id; -	m.type = xwm->atoms[WM_PROTOCOLS]; -	m.data.data32[0] = xwm->atoms[WM_TAKE_FOCUS]; -	m.data.data32[1] = XCB_TIME_CURRENT_TIME; -	xcb_send_event_checked(xwm->xcb_conn, 0, surface->window_id, -		XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT, (char*)&m); -	xcb_set_input_focus_checked(xwm->xcb_conn, XCB_INPUT_FOCUS_POINTER_ROOT, -		surface->window_id, XCB_CURRENT_TIME); -	xcb_configure_window_checked(xwm->xcb_conn, surface->window_id, -		XCB_CONFIG_WINDOW_STACK_MODE, (uint32_t[]){XCB_STACK_MODE_ABOVE}); +	if (surface) { +		xcb_client_message_event_t m = {0}; +		m.response_type = XCB_CLIENT_MESSAGE; +		m.format = 32; +		m.window = surface->window_id; +		m.type = xwm->atoms[WM_PROTOCOLS]; +		m.data.data32[0] = xwm->atoms[WM_TAKE_FOCUS]; +		m.data.data32[1] = XCB_TIME_CURRENT_TIME; +		xcb_send_event_checked(xwm->xcb_conn, 0, surface->window_id, +			XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT, (char*)&m); +		xcb_set_input_focus_checked(xwm->xcb_conn, XCB_INPUT_FOCUS_POINTER_ROOT, +			surface->window_id, XCB_CURRENT_TIME); +		xcb_configure_window_checked(xwm->xcb_conn, surface->window_id, +			XCB_CONFIG_WINDOW_STACK_MODE, (uint32_t[]){XCB_STACK_MODE_ABOVE}); +	} else { +		wlr_log(L_DEBUG, "Deactivating xwayland"); +		xcb_set_input_focus_checked(xwm->xcb_conn, XCB_INPUT_FOCUS_NONE, +			-1, XCB_CURRENT_TIME); +	}  	xcb_flush(xwm->xcb_conn);  } @@ -735,6 +741,7 @@ void wlr_xwayland_surface_configure(struct wlr_xwayland *wlr_xwayland,  		XCB_CONFIG_WINDOW_BORDER_WIDTH;  	uint32_t values[] = {x, y, width, height, 0};  	xcb_configure_window(xwm->xcb_conn, surface->window_id, mask, values); +	xcb_flush(xwm->xcb_conn);  }  void wlr_xwayland_surface_close(struct wlr_xwayland *wlr_xwayland, | 
