diff options
Diffstat (limited to 'rootston')
| -rw-r--r-- | rootston/config.c | 16 | ||||
| -rw-r--r-- | rootston/cursor.c | 7 | ||||
| -rw-r--r-- | rootston/keyboard.c | 47 | ||||
| -rw-r--r-- | rootston/output.c | 23 | ||||
| -rw-r--r-- | rootston/xdg_shell_v6.c | 15 | ||||
| -rw-r--r-- | rootston/xwayland.c | 18 | 
6 files changed, 120 insertions, 6 deletions
| diff --git a/rootston/config.c b/rootston/config.c index 6f81170b..b3fd4f01 100644 --- a/rootston/config.c +++ b/rootston/config.c @@ -1,6 +1,7 @@  #ifndef _POSIX_C_SOURCE  #define _POSIX_C_SOURCE 200809L  #endif +#include <assert.h>  #include <stdlib.h>  #include <limits.h>  #include <getopt.h> @@ -244,6 +245,21 @@ static int config_ini_handler(void *user, const char *section, const char *name,  			} else {  				wlr_log(L_ERROR, "got unknown transform value: %s", value);  			} +		} else if (strcmp(name, "mode") == 0) { +			char *end; +			oc->mode.width = strtol(value, &end, 10); +			assert(*end == 'x'); +			++end; +			oc->mode.height = strtol(end, &end, 10); +			if (*end) { +				assert(*end == '@'); +				++end; +				oc->mode.refresh_rate = strtof(end, &end); +				assert(strcmp("Hz", end) == 0); +			} +			wlr_log(L_DEBUG, "Configured output %s with mode %dx%d@%f", +					oc->name, oc->mode.width, oc->mode.height, +					oc->mode.refresh_rate);  		}  	} else if (strcmp(section, "cursor") == 0) {  		if (strcmp(name, "map-to-output") == 0) { diff --git a/rootston/cursor.c b/rootston/cursor.c index 2cf90539..917e876c 100644 --- a/rootston/cursor.c +++ b/rootston/cursor.c @@ -160,6 +160,13 @@ void cursor_update_position(struct roots_input *input, uint32_t time) {  				width += dx;  			} +			if (width < 0) { +				width = 0; +			} +			if (height < 0) { +				height = 0; +			} +  			// TODO we might need one configure event for this  			if (active_x != input->active_view->x ||  					active_y != input->active_view->y) { diff --git a/rootston/keyboard.c b/rootston/keyboard.c index ed0ca135..f513f753 100644 --- a/rootston/keyboard.c +++ b/rootston/keyboard.c @@ -53,7 +53,13 @@ static void keyboard_binding_execute(struct roots_keyboard *keyboard,  	}  } -static void keyboard_keysym_press(struct roots_keyboard *keyboard, +/** + * Process a keypress from the keyboard. + * + * Returns true if the keysym was handled by a binding and false if the event + * should be propagated to clients. + */ +static bool keyboard_keysym_press(struct roots_keyboard *keyboard,  		xkb_keysym_t keysym) {  	ssize_t i = keyboard_pressed_keysym_index(keyboard, keysym);  	if (i < 0) { @@ -74,7 +80,7 @@ static void keyboard_keysym_press(struct roots_keyboard *keyboard,  				wlr_session_change_vt(session, vt);  			}  		} -		return; +		return true;  	}  	uint32_t modifiers = wlr_keyboard_get_modifiers(keyboard->device->keyboard); @@ -96,8 +102,11 @@ static void keyboard_keysym_press(struct roots_keyboard *keyboard,  		if (ok) {  			keyboard_binding_execute(keyboard, bc->command); +			return true;  		}  	} + +	return false;  }  static void keyboard_keysym_release(struct roots_keyboard *keyboard, @@ -116,13 +125,36 @@ static void keyboard_key_notify(struct wl_listener *listener, void *data) {  	const xkb_keysym_t *syms;  	int syms_len = xkb_state_key_get_syms(keyboard->device->keyboard->xkb_state,  		keycode, &syms); + +	bool handled = false;  	for (int i = 0; i < syms_len; i++) {  		if (event->state == WLR_KEY_PRESSED) { -			keyboard_keysym_press(keyboard, syms[i]); +			bool keysym_handled = keyboard_keysym_press(keyboard, syms[i]); +			handled = handled || keysym_handled;  		} else { // WLR_KEY_RELEASED  			keyboard_keysym_release(keyboard, syms[i]);  		}  	} + +	if (!handled) { +		wlr_seat_set_keyboard(keyboard->input->wl_seat, keyboard->device); +		wlr_seat_keyboard_notify_key(keyboard->input->wl_seat, +			(uint32_t)(event->time_usec / 1000), event->keycode, event->state); +	} +} + +static void keyboard_modifiers_notify(struct wl_listener *listener, void *data) { +	struct roots_keyboard *r_keyboard = +		wl_container_of(listener, r_keyboard, modifiers); +	struct wlr_seat *seat = r_keyboard->input->wl_seat; +	struct wlr_keyboard *keyboard = r_keyboard->device->keyboard; +	wlr_seat_set_keyboard(seat, r_keyboard->device); +	wlr_seat_keyboard_notify_modifiers(seat, +		keyboard->modifiers.depressed, +		keyboard->modifiers.latched, +		keyboard->modifiers.locked, +		keyboard->modifiers.group); +  }  static void keyboard_config_merge(struct keyboard_config *config, @@ -155,8 +187,13 @@ void keyboard_add(struct wlr_input_device *device, struct roots_input *input) {  	device->data = keyboard;  	keyboard->device = device;  	keyboard->input = input; +  	keyboard->key.notify = keyboard_key_notify;  	wl_signal_add(&device->keyboard->events.key, &keyboard->key); + +	keyboard->modifiers.notify = keyboard_modifiers_notify; +	wl_signal_add(&device->keyboard->events.modifiers, &keyboard->modifiers); +  	wl_list_insert(&input->keyboards, &keyboard->link);  	struct keyboard_config config; @@ -188,14 +225,12 @@ void keyboard_add(struct wlr_input_device *device, struct roots_input *input) {  	wlr_keyboard_set_keymap(device->keyboard, xkb_map_new_from_names(context,  		&rules, XKB_KEYMAP_COMPILE_NO_FLAGS));  	xkb_context_unref(context); - -	wlr_seat_attach_keyboard(input->wl_seat, device);  }  void keyboard_remove(struct wlr_input_device *device, struct roots_input *input) {  	struct roots_keyboard *keyboard = device->data; -	wlr_seat_detach_keyboard(input->wl_seat, device->keyboard);  	wl_list_remove(&keyboard->key.link); +	wl_list_remove(&keyboard->modifiers.link);  	wl_list_remove(&keyboard->link);  	free(keyboard);  } diff --git a/rootston/output.c b/rootston/output.c index 5fcd02a2..6bc28996 100644 --- a/rootston/output.c +++ b/rootston/output.c @@ -165,6 +165,26 @@ static void output_frame_notify(struct wl_listener *listener, void *data) {  	output->last_frame = desktop->last_frame = now;  } +static void set_mode(struct wlr_output *output, struct output_config *oc) { +	struct wlr_output_mode *mode, *best = NULL; +	int mhz = (int)(oc->mode.refresh_rate * 1000); +	wl_list_for_each(mode, &output->modes, link) { +		if (mode->width == oc->mode.width && mode->height == oc->mode.height) { +			if (mode->refresh == mhz) { +				best = mode; +				break; +			} +			best = mode; +		} +	} +	if (!best) { +		wlr_log(L_ERROR, "Configured mode for %s not available", output->name); +	} else { +		wlr_log(L_DEBUG, "Assigning configured mode to %s", output->name); +		wlr_output_set_mode(output, best); +	} +} +  void output_add_notify(struct wl_listener *listener, void *data) {  	struct wlr_output *wlr_output = data;  	struct roots_desktop *desktop = wl_container_of(listener, desktop, output_add); @@ -191,6 +211,9 @@ void output_add_notify(struct wl_listener *listener, void *data) {  	struct output_config *output_config = config_get_output(config, wlr_output);  	if (output_config) { +		if (output_config->mode.width) { +			set_mode(wlr_output, output_config); +		}  		wlr_output_transform(wlr_output, output_config->transform);  		wlr_output_layout_add(desktop->layout,  				wlr_output, output_config->x, output_config->y); diff --git a/rootston/xdg_shell_v6.c b/rootston/xdg_shell_v6.c index 85871144..4f284851 100644 --- a/rootston/xdg_shell_v6.c +++ b/rootston/xdg_shell_v6.c @@ -29,6 +29,21 @@ static void resize(struct roots_view *view, uint32_t width, uint32_t height) {  	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) { +		struct wlr_xdg_toplevel_v6_state *state = +			&surf->toplevel_state->current; +		if (width < state->min_width) { +			width = state->min_width; +		} else if (state->max_width > 0 && +				width < state->max_width) { +			width = state->max_width; +		} +		if (height < state->min_height) { +			height = state->min_height; +		} else if (state->max_height > 0 && +				height < state->max_height) { +			height = state->max_height; +		} +  		wlr_xdg_toplevel_v6_set_size(surf, width, height);  	}  } diff --git a/rootston/xwayland.c b/rootston/xwayland.c index 3d066093..2d7fe946 100644 --- a/rootston/xwayland.c +++ b/rootston/xwayland.c @@ -18,6 +18,24 @@ static void activate(struct roots_view *view, bool active) {  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; + +	struct wlr_xwayland_surface_size_hints *size_hints = +		xwayland_surface->size_hints; +	if (size_hints != NULL) { +		if (width < (uint32_t)size_hints->min_width) { +			width = size_hints->min_width; +		} else if (size_hints->max_width > 0 && +				width > (uint32_t)size_hints->max_width) { +			width = size_hints->max_width; +		} +		if (height < (uint32_t)size_hints->min_height) { +			height = size_hints->min_height; +		} else if (size_hints->max_height > 0 && +				height > (uint32_t)size_hints->max_height) { +			height = size_hints->max_height; +		} +	} +  	wlr_xwayland_surface_configure(view->desktop->xwayland, xwayland_surface,  		xwayland_surface->x, xwayland_surface->y, width, height);  } | 
