diff -Nru phoc-0.6.0/debian/changelog phoc-0.8.0/debian/changelog --- phoc-0.6.0/debian/changelog 2021-03-03 11:03:59.000000000 +0000 +++ phoc-0.8.0/debian/changelog 2021-09-01 09:49:34.000000000 +0000 @@ -1,8 +1,34 @@ -phoc (0.6.0-1build1) hirsute; urgency=medium +phoc (0.8.0-2) unstable; urgency=medium - * No-change rebuild against new libwlroots7 + * Upload to unstable, no changes needed - -- Lukas Märdian Wed, 03 Mar 2021 12:03:59 +0100 + -- Arnaud Ferraris Wed, 01 Sep 2021 11:49:34 +0200 + +phoc (0.8.0-1) experimental; urgency=medium + + [ Guido Günther ] + * build: Require gsettings-desktop-schemas. + We need those for pointer/mouse related enums + + [ Arnaud Ferraris ] + * New upstream version 0.8.0 + + -- Arnaud Ferraris Wed, 14 Jul 2021 15:09:18 +0200 + +phoc (0.7.1-1) experimental; urgency=medium + + * Team upload. + * New upstream version 0.7.1 + * d/control: Version wlroots dependency. + Latest supported is 0.12.0. + + -- Guido Günther Mon, 21 Jun 2021 17:16:08 +0200 + +phoc (0.7.0-1) experimental; urgency=medium + + * New upstream version 0.7.0 + + -- Arnaud Ferraris Fri, 19 Mar 2021 23:32:21 +0100 phoc (0.6.0-1) unstable; urgency=medium diff -Nru phoc-0.6.0/debian/control phoc-0.8.0/debian/control --- phoc-0.6.0/debian/control 2021-03-03 11:03:59.000000000 +0000 +++ phoc-0.8.0/debian/control 2021-07-14 13:14:51.000000000 +0000 @@ -1,10 +1,10 @@ Source: phoc Priority: optional -Maintainer: Ubuntu Developers -XSBC-Original-Maintainer: DebianOnMobile Maintainers +Maintainer: DebianOnMobile Maintainers Uploaders: Arnaud Ferraris Build-Depends: debhelper-compat (= 13), + gsettings-desktop-schemas, libglib2.0-dev, libgnome-desktop-3-dev, libinput-dev, @@ -14,9 +14,10 @@ meson (>= 0.47.0), pkg-config, wayland-protocols, - libwlroots-dev (>= 0.10.0), + libxcb1-dev, + libwlroots-dev (>= 0.12.0), + libwlroots-dev (<< 0.13.0), # to run the tests - gsettings-desktop-schemas , mutter-common , xvfb , xauth , diff -Nru phoc-0.6.0/.gitlab-ci.yml phoc-0.8.0/.gitlab-ci.yml --- phoc-0.6.0/.gitlab-ci.yml 2021-01-04 19:46:36.000000000 +0000 +++ phoc-0.8.0/.gitlab-ci.yml 2021-07-10 00:06:41.000000000 +0000 @@ -1,5 +1,7 @@ include: - 'https://source.puri.sm/Librem5/librem5-ci/raw/master/librem5-pipeline-definitions.yml' + - 'https://source.puri.sm/Librem5/librem5-ci/raw/master/librem5-pipeline-amber-jobs.yml' + - 'https://source.puri.sm/Librem5/librem5-ci/raw/master/librem5-pipeline-byzantium-jobs.yml' stages: - build @@ -12,7 +14,6 @@ ALPINE_EDGE_DEPS: | git meson ninja gnome-desktop-dev gobject-introspection-dev libinput-dev wayland-dev wayland-protocols libxkbcommon-dev wlroots-dev - DEB_BUILD_PROFILES: pkg.phoc.embedwlroots XVFB_RUN: xvfb-run -s -noreset .tags: &tags @@ -57,6 +58,9 @@ artifacts: paths: - _build + except: + variables: + - $PKG_ONLY == "1" build-with-xwayland-debian-bullseye: stage: build @@ -66,6 +70,9 @@ BUILD_ARGS: -Dxwayland=enabled <<: *tags <<: *build + except: + variables: + - $PKG_ONLY == "1" build-without-xwayland-debian-buster: stage: build @@ -75,6 +82,9 @@ BUILD_ARGS: -Dxwayland=disabled <<: *tags <<: *build + except: + variables: + - $PKG_ONLY == "1" build-with-xwayland-alpinelinux-edge: stage: build @@ -85,6 +95,9 @@ <<: *tags <<: *build allow_failure: true + except: + variables: + - $PKG_ONLY == "1" build-without-xwayland-alpinelinux-edge: stage: build @@ -95,13 +108,16 @@ <<: *tags <<: *build allow_failure: true + except: + variables: + - $PKG_ONLY == "1" unit-test-with-xwayland-debian-buster: <<: *tags stage: test image: debian:buster - dependencies: + needs: - build-with-xwayland-debian-buster before_script: *before_script_debian_buster script: @@ -112,86 +128,6 @@ when: always paths: - _build - -package-deb-with-wlroots: - <<: *tags - stage: package - image: debian:buster - dependencies: [] - before_script: *before_script_debian_buster - script: - - rm -rf "${L5_WORKING_DIR}"; mkdir -p "${L5_WORKING_DIR}" - - git submodule update --init - - dpkg-buildpackage -b -uc -us - # Must not be dynamically linked against wlroots - - ldd debian/phoc/usr/bin/phoc | grep libwlroots && exit 1 || true - - cp -l ../*.deb ../*.changes ../*.buildinfo "${L5_WORKING_DIR}/" - artifacts: - paths: - - "${L5_WORKING_DIR}" - -package-deb-without-wlroots: - <<: *tags - stage: package - image: debian:buster - variables: - DEB_BUILD_PROFILES: "" - dependencies: [] - before_script: *before_script_debian_buster - script: - - rm -rf "${L5_WORKING_DIR}"; mkdir -p "${L5_WORKING_DIR}" - - dpkg-buildpackage -b -uc -us - # Must be dynamically linked against wlroots - - ldd debian/phoc/usr/bin/phoc | grep libwlroots - - cp -l ../*.deb ../*.changes ../*.buildinfo "${L5_WORKING_DIR}/" - artifacts: - paths: - - "${L5_WORKING_DIR}" - -package-deb-with-wlroots:arm64: - tags: - - librem5:arm64 - stage: package - image: debian:buster - dependencies: [] - before_script: *before_script_debian_buster - script: - - rm -rf "${L5_WORKING_DIR}"; mkdir -p "${L5_WORKING_DIR}" - - git submodule update --init - - dpkg-buildpackage -b -uc -us - # Must not be dynamically linked against wlroots - - ldd debian/phoc/usr/bin/phoc | grep libwlroots && exit 1 || true - - cp -l ../*.deb ../*.changes ../*.buildinfo "${L5_WORKING_DIR}/" - artifacts: - paths: - - "${L5_WORKING_DIR}" - -package-deb-without-wlroots:arm64: - tags: - - librem5:arm64 - stage: package - image: debian:buster - variables: - DEB_BUILD_PROFILES: "" - dependencies: [] - before_script: *before_script_debian_buster - script: - - rm -rf "${L5_WORKING_DIR}"; mkdir -p "${L5_WORKING_DIR}" - - dpkg-buildpackage -b -uc -us - # Must be dynamically linked against wlroots - - ldd debian/phoc/usr/bin/phoc | grep libwlroots - - cp -l ../*.deb ../*.changes ../*.buildinfo "${L5_WORKING_DIR}/" - artifacts: - paths: - - "${L5_WORKING_DIR}" - -autopkgtest-debian-buster-package: - dependencies: - - package-deb-with-wlroots - extends: .l5-autopkgtest-debian-package - -lintian-debian-buster-package: - dependencies: - - package-deb-with-wlroots - extends: .l5-lintian-debian-package - + except: + variables: + - $PKG_ONLY == "1" diff -Nru phoc-0.6.0/meson.build phoc-0.8.0/meson.build --- phoc-0.6.0/meson.build 2021-01-04 19:46:36.000000000 +0000 +++ phoc-0.8.0/meson.build 2021-07-10 00:06:41.000000000 +0000 @@ -1,5 +1,5 @@ project('phoc', 'c', - version: '0.6.0', + version: '0.8.0', license: 'GPLv3+', meson_version: '>= 0.47.0', default_options: [ @@ -29,6 +29,7 @@ glib = dependency('glib-2.0', version: '>=2.50.0') gobject = dependency('gobject-2.0', version: '>=2.50.0') gnome_desktop = dependency('gnome-desktop-3.0', version: '>=3.26') +gsettings_desktop_schemas_dep = dependency('gsettings-desktop-schemas') input = dependency('libinput') drm = dependency('libdrm') pixman = dependency('pixman-1') diff -Nru phoc-0.6.0/README.md phoc-0.8.0/README.md --- phoc-0.6.0/README.md 2021-01-04 19:46:36.000000000 +0000 +++ phoc-0.8.0/README.md 2021-07-10 00:06:41.000000000 +0000 @@ -6,9 +6,20 @@ Phoc is pronounced like the English word fog. +## Dependencies +On a Debian based system run: + +```sh + sudo apt-get -y install build-essential + sudo apt-get -y build-dep . +``` + +For an explicit list of dependencies check the `Build-Depends` entry in the +[debian/control][] file. + ## Building -We use the meson (and thereby Ninja) build system for phosh. The quickest +We use the meson (and thereby Ninja) build system for phoc. The quickest way to get going is to do the following: meson . _build diff -Nru phoc-0.6.0/src/cursor.c phoc-0.8.0/src/cursor.c --- phoc-0.6.0/src/cursor.c 2021-01-04 19:46:36.000000000 +0000 +++ phoc-0.8.0/src/cursor.c 2021-07-10 00:06:41.000000000 +0000 @@ -20,14 +20,11 @@ struct roots_cursor *roots_cursor_create(struct roots_seat *seat) { struct roots_cursor *cursor = calloc(1, sizeof(struct roots_cursor)); - if (!cursor) { - return NULL; - } + g_assert (cursor); + cursor->cursor = wlr_cursor_create(); - if (!cursor->cursor) { - free(cursor); - return NULL; - } + g_assert (cursor->cursor); + cursor->default_xcursor = ROOTS_XCURSOR_DEFAULT; return cursor; } @@ -101,7 +98,7 @@ } } -static bool roots_handle_shell_reveal(struct wlr_surface *surface, double lx, double ly, double threshold) { +static bool roots_handle_shell_reveal(struct wlr_surface *surface, double lx, double ly, int threshold) { PhocServer *server = phoc_server_get_default (); PhocDesktop *desktop = server->desktop; @@ -156,10 +153,10 @@ } } - if ((top && ly <= output_box->y + threshold * output_box->height) || - (bottom && ly >= output_box->y + (1.0 - threshold) * output_box->height - 1) || - (left && lx <= output_box->x + threshold * output_box->width) || - (right && lx >= output_box->x + (1.0 - threshold) * output_box->width - 1)) { + if ((top && ly <= output_box->y + threshold) || + (bottom && ly >= output_box->y + output_box->height - 1 - threshold) || + (left && lx <= output_box->x + threshold) || + (right && lx >= output_box->x + output_box->width - 1 - threshold)) { if (output->fullscreen_view) { output->force_shell_reveal = true; phoc_output_damage_whole(output); @@ -194,7 +191,7 @@ return; } - if (cursor->cursor_client != client) { + if (cursor->cursor_client != client || !client) { roots_seat_maybe_set_cursor (seat, NULL); cursor->cursor_client = client; } @@ -244,6 +241,8 @@ void roots_cursor_update_position(struct roots_cursor *cursor, uint32_t time) { + PhocServer *server = phoc_server_get_default (); + PhocDesktop *desktop = server->desktop; struct roots_seat *seat = cursor->seat; struct roots_view *view; switch (cursor->mode) { @@ -253,15 +252,34 @@ case ROOTS_CURSOR_MOVE: view = roots_seat_get_focus(seat); if (view != NULL) { + struct wlr_box geom; + view_get_geometry(view, &geom); double dx = cursor->cursor->x - cursor->offs_x; double dy = cursor->cursor->y - cursor->offs_y; - view_move(view, cursor->view_x + dx, - cursor->view_y + dy); + + struct wlr_output *wlr_output = wlr_output_layout_output_at(desktop->layout, cursor->cursor->x, cursor->cursor->y); + struct wlr_box *output_box = wlr_output_layout_get_box(desktop->layout, wlr_output); + + bool output_is_landscape = output_box->width > output_box->height; + + if (cursor->cursor->y < output_box->y + PHOC_EDGE_SNAP_THRESHOLD) { + view_maximize(view, wlr_output); + } else if (output_is_landscape && cursor->cursor->x < output_box->x + PHOC_EDGE_SNAP_THRESHOLD) { + view_tile(view, PHOC_VIEW_TILE_LEFT, wlr_output); + } else if (output_is_landscape && cursor->cursor->x > output_box->x + output_box->width - PHOC_EDGE_SNAP_THRESHOLD) { + view_tile(view, PHOC_VIEW_TILE_RIGHT, wlr_output); + } else { + view_restore(view); + view_move(view, cursor->view_x + dx - geom.x * view->scale, + cursor->view_y + dy - geom.y * view->scale); + } } break; case ROOTS_CURSOR_RESIZE: view = roots_seat_get_focus(seat); if (view != NULL) { + struct wlr_box geom; + view_get_geometry(view, &geom); double dx = cursor->cursor->x - cursor->offs_x; double dy = cursor->cursor->y - cursor->offs_y; double x = view->box.x; @@ -269,7 +287,7 @@ int width = cursor->view_width; int height = cursor->view_height; if (cursor->resize_edges & WLR_EDGE_TOP) { - y = cursor->view_y + dy; + y = cursor->view_y + dy - geom.y * view->scale; height -= dy; if (height < 1) { y += height; @@ -278,7 +296,7 @@ height += dy; } if (cursor->resize_edges & WLR_EDGE_LEFT) { - x = cursor->view_x + dx; + x = cursor->view_x + dx - geom.x * view->scale; width -= dx; if (width < 1) { x += width; @@ -464,6 +482,12 @@ wlr_cursor_absolute_to_layout_coords(cursor->cursor, event->device, event->x, event->y, &lx, &ly); + if (seat->touch_id == -1 && cursor->mode == ROOTS_CURSOR_PASSTHROUGH) { + seat->touch_id = event->touch_id; + seat->touch_x = lx; + seat->touch_y = ly; + } + double sx, sy; struct roots_view *view; struct wlr_surface *surface = phoc_desktop_surface_at( @@ -511,10 +535,20 @@ struct wlr_event_touch_up *event) { struct wlr_touch_point *point = wlr_seat_touch_get_point(cursor->seat->seat, event->touch_id); + + if (cursor->seat->touch_id == event->touch_id) { + cursor->seat->touch_id = -1; + } + if (!point) { return; } + if (cursor->mode != ROOTS_CURSOR_PASSTHROUGH) { + cursor->mode = ROOTS_CURSOR_PASSTHROUGH; + roots_cursor_update_focus(cursor); + } + wlr_seat_touch_notify_up(cursor->seat->seat, event->time_msec, event->touch_id); } @@ -601,6 +635,11 @@ if (event->touch_id == cursor->seat->touch_id) { cursor->seat->touch_x = lx; cursor->seat->touch_y = ly; + + if (cursor->mode != ROOTS_CURSOR_PASSTHROUGH) { + wlr_cursor_warp(cursor->cursor, NULL, lx, ly); + roots_cursor_update_position(cursor, event->time_msec); + } } } diff -Nru phoc-0.6.0/src/cursor.h phoc-0.8.0/src/cursor.h --- phoc-0.6.0/src/cursor.h 2021-01-04 19:46:36.000000000 +0000 +++ phoc-0.8.0/src/cursor.h 2021-07-10 00:06:41.000000000 +0000 @@ -4,8 +4,9 @@ #include #include "seat.h" -#define PHOC_SHELL_REVEAL_TOUCH_THRESHOLD 0.015 -#define PHOC_SHELL_REVEAL_POINTER_THRESHOLD 0.0 +#define PHOC_SHELL_REVEAL_TOUCH_THRESHOLD 10 +#define PHOC_SHELL_REVEAL_POINTER_THRESHOLD 0 +#define PHOC_EDGE_SNAP_THRESHOLD 20 enum roots_cursor_mode { ROOTS_CURSOR_PASSTHROUGH = 0, diff -Nru phoc-0.6.0/src/desktop.c phoc-0.8.0/src/desktop.c --- phoc-0.6.0/src/desktop.c 2021-01-04 19:46:36.000000000 +0000 +++ phoc-0.8.0/src/desktop.c 2021-07-10 00:06:41.000000000 +0000 @@ -15,7 +15,6 @@ #include #include #include -#include #include #include #include @@ -547,16 +546,6 @@ #ifdef PHOC_XWAYLAND const char *cursor_default = ROOTS_XCURSOR_DEFAULT; #endif - struct roots_cursor_config *cc = - roots_config_get_cursor(config, ROOTS_CONFIG_DEFAULT_SEAT_NAME); - if (cc != NULL) { - cursor_theme = cc->theme; -#ifdef PHOC_XWAYLAND - if (cc->default_image != NULL) { - cursor_default = cc->default_image; - } -#endif - } char cursor_size_fmt[16]; snprintf(cursor_size_fmt, sizeof(cursor_size_fmt), @@ -610,7 +599,6 @@ wlr_server_decoration_manager_set_default_mode(self->server_decoration_manager, WLR_SERVER_DECORATION_MANAGER_MODE_CLIENT); self->idle = wlr_idle_create(server->wl_display); - self->idle_inhibit = wlr_idle_inhibit_v1_create(server->wl_display); self->primary_selection_device_manager = wlr_gtk_primary_selection_device_manager_create(server->wl_display); self->input_inhibit = @@ -785,11 +773,16 @@ self->maximize = enable; /* Disabling auto-maximize leaves all views in their current position */ - if (!enable) + if (!enable) { + wl_list_for_each (view, &self->views, link) + view_appear_activated (view, phoc_input_view_has_focus (phoc_server_get_default()->input, view)); return; + } - wl_list_for_each (view, &self->views, link) + wl_list_for_each (view, &self->views, link) { view_auto_maximize (view); + view_appear_activated (view, true); + } } gboolean diff -Nru phoc-0.6.0/src/desktop.h phoc-0.8.0/src/desktop.h --- phoc-0.6.0/src/desktop.h 2021-01-04 19:46:36.000000000 +0000 +++ phoc-0.8.0/src/desktop.h 2021-07-10 00:06:41.000000000 +0000 @@ -9,7 +9,6 @@ #include #include #include -#include #include #include #include @@ -71,7 +70,6 @@ struct wlr_xdg_decoration_manager_v1 *xdg_decoration_manager; struct wlr_gtk_primary_selection_device_manager *primary_selection_device_manager; struct wlr_idle *idle; - struct wlr_idle_inhibit_manager_v1 *idle_inhibit; struct wlr_input_inhibit_manager *input_inhibit; struct wlr_layer_shell_v1 *layer_shell; struct wlr_input_method_manager_v2 *input_method; diff -Nru phoc-0.6.0/src/input.c phoc-0.8.0/src/input.c --- phoc-0.6.0/src/input.c 2021-01-04 19:46:36.000000000 +0000 +++ phoc-0.8.0/src/input.c 2021-07-10 00:06:41.000000000 +0000 @@ -7,27 +7,12 @@ #include #include #include -#include -#include -#include -#include -#include -#ifdef PHOC_XWAYLAND -#include -#endif #include "input.h" #include "keyboard.h" #include "seat.h" G_DEFINE_TYPE (PhocInput, phoc_input, G_TYPE_OBJECT); -enum { - PROP_0, - PROP_CONFIG, - PROP_LAST_PROP, -}; -static GParamSpec *props[PROP_LAST_PROP]; - const char * phoc_input_get_device_type (enum wlr_input_device_type type) { @@ -49,43 +34,6 @@ } } -static void -phoc_input_set_property (GObject *object, - guint property_id, - const GValue *value, - GParamSpec *pspec) -{ - PhocInput *self = PHOC_INPUT (object); - - switch (property_id) { - case PROP_CONFIG: - self->config = g_value_get_pointer (value); - g_object_notify_by_pspec (G_OBJECT (self), props[PROP_CONFIG]); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - break; - } -} - -static void -phoc_input_get_property (GObject *object, - guint property_id, - GValue *value, - GParamSpec *pspec) -{ - PhocInput *self = PHOC_INPUT (object); - - switch (property_id) { - case PROP_CONFIG: - g_value_set_pointer (value, self->config); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); - break; - } -} - struct roots_seat * phoc_input_get_seat (PhocInput *self, char *name) { @@ -108,13 +56,6 @@ PhocInput *input = wl_container_of (listener, input, new_input); char *seat_name = ROOTS_CONFIG_DEFAULT_SEAT_NAME; - struct roots_device_config *dc = - roots_config_get_device (input->config, device); - - if (dc) { - seat_name = dc->seat; - } - struct roots_seat *seat = phoc_input_get_seat (input, seat_name); if (!seat) { @@ -127,17 +68,6 @@ phoc_input_get_device_type (device->type), seat_name); roots_seat_add_device (seat, device); - - if (dc && wlr_input_device_is_libinput (device)) { - struct libinput_device *libinput_dev = - wlr_libinput_get_device_handle (device); - - g_debug ("input has config, tap_enabled: %d\n", dc->tap_enabled); - if (dc->tap_enabled) { - libinput_device_config_tap_set_enabled (libinput_dev, - LIBINPUT_CONFIG_TAP_ENABLED); - } - } } static void @@ -148,9 +78,7 @@ PhocInput * phoc_input_new (struct roots_config *config) { - return g_object_new (PHOC_TYPE_INPUT, - "config", config, - NULL); + return g_object_new (PHOC_TYPE_INPUT, NULL); } static void @@ -159,7 +87,7 @@ PhocInput *self = PHOC_INPUT (object); PhocServer *server = phoc_server_get_default (); - g_debug ("Initializing roots input"); + g_debug ("Initializing phoc input"); assert (server->desktop); wl_list_init (&self->seats); @@ -181,36 +109,12 @@ } static void -phoc_input_dispose (GObject *object) -{ - PhocInput *self = PHOC_INPUT (object); - - g_clear_object (&self->config); - - G_OBJECT_CLASS (phoc_input_parent_class)->dispose (object); -} - -static void phoc_input_class_init (PhocInputClass *klass) { GObjectClass *object_class = (GObjectClass *)klass; - object_class->set_property = phoc_input_set_property; - object_class->get_property = phoc_input_get_property; - object_class->constructed = phoc_input_constructed; - object_class->dispose = phoc_input_dispose; object_class->finalize = phoc_input_finalize; - - props[PROP_CONFIG] = - g_param_spec_pointer ( - "config", - "Config", - "The config object", - G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); - - g_object_class_install_properties (object_class, PROP_LAST_PROP, props); - } struct roots_seat * diff -Nru phoc-0.6.0/src/input.h phoc-0.8.0/src/input.h --- phoc-0.6.0/src/input.h 2021-01-04 19:46:36.000000000 +0000 +++ phoc-0.8.0/src/input.h 2021-07-10 00:06:41.000000000 +0000 @@ -25,9 +25,6 @@ struct wl_listener new_input; struct wl_list seats; // roots_seat::link */ - - /* private */ - struct roots_config *config; }; PhocInput *phoc_input_new (struct roots_config *config); diff -Nru phoc-0.6.0/src/keybindings.c phoc-0.8.0/src/keybindings.c --- phoc-0.6.0/src/keybindings.c 2021-01-04 19:46:36.000000000 +0000 +++ phoc-0.8.0/src/keybindings.c 2021-07-10 00:06:41.000000000 +0000 @@ -47,7 +47,7 @@ struct roots_view *focus = roots_seat_get_focus(seat); if (focus != NULL) - view_maximize(focus); + view_maximize(focus, NULL); } static void @@ -65,7 +65,7 @@ struct roots_view *view = roots_seat_get_focus(seat); if (view != NULL) - view_tile(view, PHOC_VIEW_TILE_RIGHT); + view_tile(view, PHOC_VIEW_TILE_RIGHT, NULL); } @@ -75,7 +75,7 @@ struct roots_view *view = roots_seat_get_focus(seat); if (view != NULL) - view_tile(view, PHOC_VIEW_TILE_LEFT); + view_tile(view, PHOC_VIEW_TILE_LEFT, NULL); } @@ -88,7 +88,7 @@ if (view_is_maximized(focus)) view_restore(focus); else - view_maximize(focus); + view_maximize(focus, NULL); } } diff -Nru phoc-0.6.0/src/layer_shell.c phoc-0.8.0/src/layer_shell.c --- phoc-0.6.0/src/layer_shell.c 2021-01-04 19:46:36.000000000 +0000 +++ phoc-0.8.0/src/layer_shell.c 2021-07-10 00:06:41.000000000 +0000 @@ -281,9 +281,9 @@ struct roots_view *view; wl_list_for_each(view, &output->desktop->views, link) { if (view_is_maximized(view)) { - view_arrange_maximized(view); + view_arrange_maximized(view, NULL); } else if (view_is_tiled(view)) { - view_arrange_tiled(view); + view_arrange_tiled(view, NULL); } else if (output->desktop->maximize) { view_center(view); } diff -Nru phoc-0.6.0/src/meson.build phoc-0.8.0/src/meson.build --- phoc-0.6.0/src/meson.build 2021-01-04 19:46:36.000000000 +0000 +++ phoc-0.8.0/src/meson.build 2021-07-10 00:06:41.000000000 +0000 @@ -10,6 +10,7 @@ 'layer_shell.c', 'output.c', 'phosh.c', + 'pointer.c', 'render.c', 'seat.c', 'server.c', @@ -28,6 +29,7 @@ gio, glesv2, gnome_desktop, + gsettings_desktop_schemas_dep, math, pixman, wayland_server, diff -Nru phoc-0.6.0/src/phosh.c phoc-0.8.0/src/phosh.c --- phoc-0.6.0/src/phosh.c 2021-01-04 19:46:36.000000000 +0000 +++ phoc-0.8.0/src/phosh.c 2021-07-10 00:06:41.000000000 +0000 @@ -164,6 +164,10 @@ if (combo->keysym >= XKB_KEY_XF86MonBrightnessUp && combo->keysym <= XKB_KEY_XF86RotationLockToggle) return true; + /* misc functions */ + if (combo->keysym >= XKB_KEY_Select && combo->keysym <= XKB_KEY_Num_Lock) + return true; + return false; } @@ -181,6 +185,15 @@ if (kbevent == NULL) return; + if (combo == NULL) { + g_debug ("Failed to parse accelerator %s", accelerator); + + phosh_private_keyboard_event_send_grab_failed_event (resource, + accelerator, + PHOSH_PRIVATE_KEYBOARD_EVENT_ERROR_INVALID_KEYSYM); + return; + } + if (phosh_private_accelerator_already_subscribed (combo)) { g_debug ("Accelerator %s already subscribed to!", accelerator); diff -Nru phoc-0.6.0/src/pointer.c phoc-0.8.0/src/pointer.c --- phoc-0.6.0/src/pointer.c 1970-01-01 00:00:00.000000000 +0000 +++ phoc-0.8.0/src/pointer.c 2021-07-10 00:06:41.000000000 +0000 @@ -0,0 +1,296 @@ +#define G_LOG_DOMAIN "phoc-pointer" + +#include "config.h" + +#include "pointer.h" +#include "seat.h" + +#include +#include +#include +#include + +enum { + PROP_0, + PROP_DEVICE, + PROP_SEAT, + PROP_LAST_PROP, +}; +static GParamSpec *props[PROP_LAST_PROP]; + +G_DEFINE_TYPE (PhocPointer, phoc_pointer, G_TYPE_OBJECT); + + +static void +check_touchpad (PhocPointer *self) +{ + struct libinput_device *ldev; + + if (!wlr_input_device_is_libinput (self->device)) + return; + + ldev = wlr_libinput_get_device_handle(self->device); + if (libinput_device_config_tap_get_finger_count (ldev) == 0) + return; + + g_debug ("%s is a touchpad device", self->device->name); + self->touchpad = TRUE; +} + + +static void +phoc_pointer_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + PhocPointer *self = PHOC_POINTER (object); + + switch (property_id) { + case PROP_DEVICE: + self->device = g_value_get_pointer (value); + self->device->data = self; + check_touchpad (self); + g_object_notify_by_pspec (G_OBJECT (self), props[PROP_DEVICE]); + break; + case PROP_SEAT: + self->seat = g_value_get_pointer (value); + g_object_notify_by_pspec (G_OBJECT (self), props[PROP_SEAT]); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} + + +static void +phoc_pointer_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + PhocPointer *self = PHOC_POINTER (object); + + switch (property_id) { + case PROP_DEVICE: + g_value_set_pointer (value, self->device); + break; + case PROP_SEAT: + g_value_set_pointer (value, self->seat); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} + + +static void +on_mouse_settings_changed (PhocPointer *self, + const gchar *key, + GSettings *settings) +{ + struct libinput_device *ldev; + gboolean enabled; + gdouble speed; + + g_debug ("Setting changed, reloading mouse settings"); + + g_assert (PHOC_IS_POINTER (self)); + g_assert (G_IS_SETTINGS (settings)); + + if (!wlr_input_device_is_libinput (self->device)) + return; + + ldev = wlr_libinput_get_device_handle(self->device); + if (libinput_device_config_scroll_has_natural_scroll (ldev)) { + enabled = g_settings_get_boolean (settings, "natural-scroll"); + libinput_device_config_scroll_set_natural_scroll_enabled (ldev, enabled); + } + + if (libinput_device_config_middle_emulation_is_available (ldev)) { + enabled = g_settings_get_boolean (settings, "middle-click-emulation"); + libinput_device_config_middle_emulation_set_enabled (ldev, enabled); + } + + speed = g_settings_get_double (settings, "speed"); + libinput_device_config_accel_set_speed (ldev, + CLAMP (speed, -1, 1)); + + if (libinput_device_config_left_handed_is_available (ldev)) { + enabled = g_settings_get_boolean (self->mouse_settings, "left-handed"); + libinput_device_config_left_handed_set (ldev, enabled); + } +} + + +static void +on_touchpad_settings_changed (PhocPointer *self, + const gchar *key) +{ + struct libinput_device *ldev; + gboolean enabled; + gdouble speed; + enum libinput_config_scroll_method current, method; + GDesktopTouchpadHandedness handedness; + GSettings *settings; + + g_debug ("Setting changed, reloading touchpad settings"); + + g_assert (PHOC_IS_POINTER (self)); + + settings = self->touchpad_settings; + if (!wlr_input_device_is_libinput (self->device)) + return; + + ldev = wlr_libinput_get_device_handle(self->device); + + if (libinput_device_config_scroll_has_natural_scroll (ldev)) { + enabled = g_settings_get_boolean (settings, "natural-scroll"); + libinput_device_config_scroll_set_natural_scroll_enabled (ldev, enabled); + } + + enabled = g_settings_get_boolean (settings, "tap-to-click"); + libinput_device_config_tap_set_enabled (ldev, enabled ? + LIBINPUT_CONFIG_TAP_ENABLED : + LIBINPUT_CONFIG_TAP_DISABLED); + + enabled = g_settings_get_boolean (settings, "tap-and-drag"); + libinput_device_config_tap_set_drag_enabled (ldev, + enabled ? + LIBINPUT_CONFIG_DRAG_ENABLED : + LIBINPUT_CONFIG_DRAG_DISABLED); + + enabled = g_settings_get_boolean (settings, "tap-and-drag-lock"); + libinput_device_config_tap_set_drag_lock_enabled (ldev, + enabled ? + LIBINPUT_CONFIG_DRAG_LOCK_ENABLED : + LIBINPUT_CONFIG_DRAG_LOCK_DISABLED); + + enabled = g_settings_get_boolean (settings, "disable-while-typing"); + libinput_device_config_dwt_set_enabled (ldev, + enabled ? + LIBINPUT_CONFIG_DWT_ENABLED : + LIBINPUT_CONFIG_DWT_DISABLED); + + if (libinput_device_config_middle_emulation_is_available (ldev)) { + enabled = g_settings_get_boolean (settings, "middle-click-emulation"); + libinput_device_config_middle_emulation_set_enabled (ldev, enabled); + } + + current = libinput_device_config_scroll_get_method (ldev); + current &= ~(LIBINPUT_CONFIG_SCROLL_EDGE | LIBINPUT_CONFIG_SCROLL_2FG); + enabled = g_settings_get_boolean (settings, "edge-scrolling-enabled"); + method = enabled ? LIBINPUT_CONFIG_SCROLL_EDGE : LIBINPUT_CONFIG_SCROLL_NO_SCROLL; + current |= method; + enabled = g_settings_get_boolean (settings, "two-finger-scrolling-enabled"); + method = enabled ? LIBINPUT_CONFIG_SCROLL_2FG : LIBINPUT_CONFIG_SCROLL_NO_SCROLL; + current |= method; + libinput_device_config_scroll_set_method (ldev, current | method); + + speed = g_settings_get_double (settings, "speed"); + libinput_device_config_accel_set_speed (ldev, + CLAMP (speed, -1, 1)); + + handedness = g_settings_get_enum (self->touchpad_settings, "left-handed"); + switch (handedness) { + case G_DESKTOP_TOUCHPAD_HANDEDNESS_RIGHT: + enabled = FALSE; + break; + case G_DESKTOP_TOUCHPAD_HANDEDNESS_LEFT: + enabled = TRUE; + break; + case G_DESKTOP_TOUCHPAD_HANDEDNESS_MOUSE: + enabled = g_settings_get_boolean (self->mouse_settings, "left-handed"); + break; + default: + g_assert_not_reached (); + } + if (libinput_device_config_left_handed_is_available (ldev)) + libinput_device_config_left_handed_set (ldev, enabled); +} + + +static void +phoc_pointer_constructed (GObject *object) +{ + PhocPointer *self = PHOC_POINTER (object); + + G_OBJECT_CLASS (phoc_pointer_parent_class)->constructed (object); + + self->mouse_settings = g_settings_new ("org.gnome.desktop.peripherals.mouse"); + if (self->touchpad) { + self->touchpad_settings = g_settings_new ("org.gnome.desktop.peripherals.touchpad"); + + g_signal_connect_swapped (self->touchpad_settings, + "changed", + G_CALLBACK (on_touchpad_settings_changed), + self); + /* "left-handed" is read from mouse settings */ + g_signal_connect_swapped (self->mouse_settings, + "changed::left-handed", + G_CALLBACK (on_touchpad_settings_changed), + self); + on_touchpad_settings_changed (self, NULL); + } else { + g_signal_connect_swapped (self->mouse_settings, + "changed", + G_CALLBACK (on_mouse_settings_changed), + self); + on_mouse_settings_changed (self, NULL, self->mouse_settings); + } +} + + +static void +phoc_pointer_dispose(GObject *object) +{ + PhocPointer *self = PHOC_POINTER (object); + + g_clear_object (&self->touchpad_settings); + g_clear_object (&self->mouse_settings); + + G_OBJECT_CLASS (phoc_pointer_parent_class)->dispose (object); +} + + +static void +phoc_pointer_class_init (PhocPointerClass *klass) +{ + GObjectClass *object_class = (GObjectClass *)klass; + + object_class->set_property = phoc_pointer_set_property; + object_class->get_property = phoc_pointer_get_property; + + object_class->constructed = phoc_pointer_constructed; + object_class->dispose = phoc_pointer_dispose; + + props[PROP_DEVICE] = + g_param_spec_pointer ("device", + "Device", + "The device object", + G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + props[PROP_SEAT] = + g_param_spec_pointer ("seat", + "Seat", + "The seat this pointer belongs to", + G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties (object_class, PROP_LAST_PROP, props); +} + +static void +phoc_pointer_init (PhocPointer *self) +{ +} + +PhocPointer * +phoc_pointer_new (struct wlr_input_device *device, struct roots_seat *seat) +{ + return g_object_new (PHOC_TYPE_POINTER, + "device", device, + "seat", seat, + NULL); +} diff -Nru phoc-0.6.0/src/pointer.h phoc-0.8.0/src/pointer.h --- phoc-0.6.0/src/pointer.h 1970-01-01 00:00:00.000000000 +0000 +++ phoc-0.8.0/src/pointer.h 2021-07-10 00:06:41.000000000 +0000 @@ -0,0 +1,30 @@ +#pragma once + +#include "input.h" + +#include +#include + +#define PHOC_TYPE_POINTER (phoc_pointer_get_type ()) + +G_DECLARE_FINAL_TYPE (PhocPointer, phoc_pointer, PHOC, POINTER, GObject); + +/* TODO: we keep the struct public due to the list links and + notifiers but we should avoid other member access */ +struct _PhocPointer { + GObject parent; + + struct wlr_input_device *device; + struct wl_listener device_destroy; + struct wl_list link; + + /* private */ + GSettings *input_settings; + struct roots_seat *seat; + gboolean touchpad; + GSettings *touchpad_settings; + GSettings *mouse_settings; +}; + +PhocPointer *phoc_pointer_new (struct wlr_input_device *device, + struct roots_seat *seat); diff -Nru phoc-0.6.0/src/render.c phoc-0.8.0/src/render.c --- phoc-0.6.0/src/render.c 2021-01-04 19:46:36.000000000 +0000 +++ phoc-0.8.0/src/render.c 2021-07-10 00:06:41.000000000 +0000 @@ -282,15 +282,19 @@ return false; } - wlr_presentation_surface_sampled(output->desktop->presentation, surface); - #if WLR_VERSION_MAJOR == 0 && WLR_VERSION_MINOR < 11 if (!wlr_output_attach_buffer(wlr_output, surface->buffer)) { return false; } #else wlr_output_attach_buffer(wlr_output, &surface->buffer->base); + if (!wlr_output_test(wlr_output)) { + return false; + } #endif + + wlr_presentation_surface_sampled_on_output(output->desktop->presentation, surface, output->wlr_output); + return wlr_output_commit(wlr_output); } diff -Nru phoc-0.6.0/src/seat.c phoc-0.8.0/src/seat.c --- phoc-0.6.0/src/seat.c 2021-01-04 19:46:36.000000000 +0000 +++ phoc-0.8.0/src/seat.c 2021-07-10 00:06:41.000000000 +0000 @@ -22,6 +22,7 @@ #include #include "cursor.h" #include "keyboard.h" +#include "pointer.h" #include "seat.h" #include "text_input.h" #include "touch.h" @@ -484,7 +485,7 @@ PhocDesktop *desktop = server->desktop; struct wlr_cursor *cursor = seat->cursor->cursor; - struct roots_pointer *pointer; + PhocPointer *pointer; PhocTouch *touch; struct roots_tablet *tablet; PhocOutput *output; @@ -527,9 +528,7 @@ static void roots_seat_init_cursor(struct roots_seat *seat) { PhocServer *server = phoc_server_get_default (); seat->cursor = roots_cursor_create(seat); - if (!seat->cursor) { - return; - } + seat->cursor->seat = seat; struct wlr_cursor *wlr_cursor = seat->cursor->cursor; PhocDesktop *desktop = server->desktop; @@ -763,6 +762,8 @@ // TODO: probably more to be freed here wl_list_remove(&seat->destroy.link); + roots_input_method_relay_destroy(&seat->im_relay); + struct roots_seat_view *view, *nview; wl_list_for_each_safe(view, nview, &seat->views, link) { seat_view_destroy(view); @@ -791,6 +792,8 @@ seat->input = input; + seat->touch_id = -1; + seat->seat = wlr_seat_create(server->wl_display, name); if (!seat->seat) { free(seat); @@ -875,29 +878,21 @@ } static void handle_pointer_destroy(struct wl_listener *listener, void *data) { - struct roots_pointer *pointer = - wl_container_of(listener, pointer, device_destroy); + PhocPointer *pointer = wl_container_of(listener, pointer, device_destroy); struct roots_seat *seat = pointer->seat; wl_list_remove(&pointer->link); wlr_cursor_detach_input_device(seat->cursor->cursor, pointer->device); wl_list_remove(&pointer->device_destroy.link); - free(pointer); + g_object_unref (pointer); seat_update_capabilities(seat); } static void seat_add_pointer(struct roots_seat *seat, struct wlr_input_device *device) { - struct roots_pointer *pointer = calloc(1, sizeof(struct roots_pointer)); - if (!pointer) { - wlr_log(WLR_ERROR, "could not allocate pointer for seat"); - return; - } + PhocPointer *pointer = phoc_pointer_new (device, seat); - device->data = pointer; - pointer->device = device; - pointer->seat = seat; wl_list_insert(&seat->pointers, &pointer->link); pointer->device_destroy.notify = handle_pointer_destroy; @@ -1207,21 +1202,12 @@ void roots_seat_configure_xcursor(struct roots_seat *seat) { PhocServer *server = phoc_server_get_default (); const char *cursor_theme = NULL; - struct roots_cursor_config *cc = - roots_config_get_cursor(seat->input->config, seat->seat->name); - if (cc != NULL) { - cursor_theme = cc->theme; - if (cc->default_image != NULL) { - seat->cursor->default_xcursor = cc->default_image; - } - } if (!seat->cursor->xcursor_manager) { seat->cursor->xcursor_manager = wlr_xcursor_manager_create(cursor_theme, ROOTS_XCURSOR_SIZE); if (seat->cursor->xcursor_manager == NULL) { - wlr_log(WLR_ERROR, "Cannot create XCursor manager for theme %s", - cursor_theme); + wlr_log(WLR_ERROR, "Cannot create XCursor manager for theme"); return; } } @@ -1488,10 +1474,7 @@ NULL, 0, NULL); } - if (seat->cursor) { - roots_cursor_update_focus(seat->cursor); - } - + roots_cursor_update_focus(seat->cursor); roots_input_method_relay_set_focus(&seat->im_relay, view->wlr_surface); } @@ -1538,10 +1521,7 @@ NULL, 0, NULL); } - if (seat->cursor) { - roots_cursor_update_focus(seat->cursor); - } - + roots_cursor_update_focus(seat->cursor); roots_input_method_relay_set_focus(&seat->im_relay, layer->surface); } @@ -1617,8 +1597,13 @@ struct roots_cursor *cursor = seat->cursor; cursor->mode = ROOTS_CURSOR_MOVE; + if (seat->touch_id != -1) { + wlr_cursor_warp(cursor->cursor, NULL, seat->touch_x, seat->touch_y); + } cursor->offs_x = cursor->cursor->x; cursor->offs_y = cursor->cursor->y; + struct wlr_box geom; + view_get_geometry(view, &geom); if (view_is_maximized(view) || view_is_tiled(view)) { // calculate normalized (0..1) position of cursor in maximized window // and make it stay the same after restoring saved size @@ -1630,8 +1615,8 @@ view->saved.y = cursor->view_y; view_restore(view); } else { - cursor->view_x = view->box.x; - cursor->view_y = view->box.y; + cursor->view_x = view->box.x + geom.x * view->scale; + cursor->view_y = view->box.y + geom.y * view->scale; } wlr_seat_pointer_clear_focus(seat->seat); @@ -1645,18 +1630,23 @@ struct roots_cursor *cursor = seat->cursor; cursor->mode = ROOTS_CURSOR_RESIZE; + if (seat->touch_id != -1) { + wlr_cursor_warp(cursor->cursor, NULL, seat->touch_x, seat->touch_y); + } cursor->offs_x = cursor->cursor->x; cursor->offs_y = cursor->cursor->y; + struct wlr_box geom; + view_get_geometry(view, &geom); if (view_is_maximized(view) || view_is_tiled(view)) { - view->saved.x = view->box.x; - view->saved.y = view->box.y; + view->saved.x = view->box.x + geom.x * view->scale; + view->saved.y = view->box.y + geom.y * view->scale; view->saved.width = view->box.width; view->saved.height = view->box.height; view_restore(view); } - cursor->view_x = view->box.x; - cursor->view_y = view->box.y; + cursor->view_x = view->box.x + geom.x * view->scale; + cursor->view_y = view->box.y + geom.y * view->scale; struct wlr_box box; view_get_box(view, &box); cursor->view_width = box.width; @@ -1690,6 +1680,7 @@ } cursor->mode = ROOTS_CURSOR_PASSTHROUGH; + roots_cursor_update_focus(seat->cursor); } struct roots_seat *input_last_active_seat(PhocInput *input) { diff -Nru phoc-0.6.0/src/seat.h phoc-0.8.0/src/seat.h --- phoc-0.6.0/src/seat.h 2021-01-04 19:46:36.000000000 +0000 +++ phoc-0.8.0/src/seat.h 2021-07-10 00:06:41.000000000 +0000 @@ -71,13 +71,6 @@ struct wl_listener destroy; }; -struct roots_pointer { - struct roots_seat *seat; - struct wlr_input_device *device; - struct wl_listener device_destroy; - struct wl_list link; -}; - struct roots_tablet { struct roots_seat *seat; struct wlr_input_device *device; diff -Nru phoc-0.6.0/src/settings.c phoc-0.8.0/src/settings.c --- phoc-0.6.0/src/settings.c 2021-01-04 19:46:36.000000000 +0000 +++ phoc-0.8.0/src/settings.c 2021-07-10 00:06:41.000000000 +0000 @@ -65,65 +65,6 @@ return true; } -static void add_switch_config(struct wl_list *switches, const char *switch_name, - const char *action, const char *command) { - struct roots_switch_config *sc = - calloc(1, sizeof(struct roots_switch_config)); - - if (strcmp(switch_name, "tablet") == 0) { - sc->switch_type = WLR_SWITCH_TYPE_TABLET_MODE; - } else if (strcmp(switch_name, "lid") == 0) { - sc->switch_type = WLR_SWITCH_TYPE_LID; - } else { - sc->switch_type = -1; - sc->name = strdup(switch_name); - } - - if (strcmp(action, "on") == 0) { - sc->switch_state = WLR_SWITCH_STATE_ON; - } else if (strcmp(action, "off") == 0) { - sc->switch_state = WLR_SWITCH_STATE_OFF; - } else if (strcmp(action, "toggle") == 0) { - sc->switch_state = WLR_SWITCH_STATE_TOGGLE; - } else { - wlr_log(WLR_ERROR, "Invalid switch action %s for switch %s:%s", - action, switch_name, action); - free(sc); - return; - } - - sc->command = strdup(command); - wl_list_insert(switches, &sc->link); -} - -static void config_handle_cursor(struct roots_config *config, - const char *seat_name, const char *name, const char *value) { - struct roots_cursor_config *cc; - bool found = false; - wl_list_for_each(cc, &config->cursors, link) { - if (strcmp(cc->seat, seat_name) == 0) { - found = true; - break; - } - } - - if (!found) { - cc = calloc(1, sizeof(struct roots_cursor_config)); - cc->seat = strdup(seat_name); - wl_list_insert(&config->cursors, &cc->link); - } - - if (strcmp(name, "theme") == 0) { - free(cc->theme); - cc->theme = strdup(value); - } else if (strcmp(name, "default-image") == 0) { - free(cc->default_image); - cc->default_image = strdup(value); - } else { - wlr_log(WLR_ERROR, "got unknown cursor config: %s", name); - } -} - static const char *output_prefix = "output:"; static const char *device_prefix = "device:"; static const char *cursor_prefix = "cursor:"; @@ -232,49 +173,13 @@ } } } else if (strncmp(cursor_prefix, section, strlen(cursor_prefix)) == 0) { - const char *seat_name = section + strlen(cursor_prefix); - config_handle_cursor(config, seat_name, name, value); + g_warning ("Found unused 'cursor:' config section. Please remove"); } else if (strcmp(section, "cursor") == 0) { - config_handle_cursor(config, ROOTS_CONFIG_DEFAULT_SEAT_NAME, name, - value); + g_warning ("Found unused 'cursor' config section. Please remove"); } else if (strncmp(device_prefix, section, strlen(device_prefix)) == 0) { - const char *device_name = section + strlen(device_prefix); - - struct roots_device_config *dc; - bool found = false; - wl_list_for_each(dc, &config->devices, link) { - if (strcmp(dc->name, device_name) == 0) { - found = true; - break; - } - } - - if (!found) { - dc = calloc(1, sizeof(struct roots_device_config)); - dc->name = strdup(device_name); - dc->seat = strdup(ROOTS_CONFIG_DEFAULT_SEAT_NAME); - wl_list_insert(&config->devices, &dc->link); - } - - if (strcmp(name, "seat") == 0) { - free(dc->seat); - dc->seat = strdup(value); - } else if (strcmp(name, "tap_enabled") == 0) { - if (strcasecmp(value, "true") == 0) { - dc->tap_enabled = true; - } else if (strcasecmp(value, "false") == 0) { - dc->tap_enabled = false; - } else { - wlr_log(WLR_ERROR, - "got unknown tap_enabled value: %s", - value); - } - } else { - wlr_log(WLR_ERROR, "got unknown device config: %s", name); - } + g_warning ("Found unused 'device:' config section. Please remove"); } else if (strncmp(switch_prefix, section, strlen(switch_prefix)) == 0) { - const char *switch_name = section + strlen(switch_prefix); - add_switch_config(&config->switches, switch_name, name, value); + g_warning ("Found unused 'switch:' config section. Please remove"); } else { wlr_log(WLR_ERROR, "got unknown config section: %s", section); } @@ -291,9 +196,6 @@ config->xwayland = true; config->xwayland_lazy = true; wl_list_init(&config->outputs); - wl_list_init(&config->devices); - wl_list_init(&config->cursors); - wl_list_init(&config->switches); config->config_path = g_strdup(config_path); @@ -341,21 +243,6 @@ free(oc); } - struct roots_device_config *dc, *dtmp = NULL; - wl_list_for_each_safe(dc, dtmp, &config->devices, link) { - free(dc->name); - free(dc->seat); - free(dc); - } - - struct roots_cursor_config *cc, *ctmp = NULL; - wl_list_for_each_safe(cc, ctmp, &config->cursors, link) { - free(cc->seat); - free(cc->theme); - free(cc->default_image); - free(cc); - } - g_object_unref (config->keybindings); free(config->config_path); @@ -376,33 +263,5 @@ } } - return NULL; -} - -struct roots_device_config *roots_config_get_device(struct roots_config *config, - struct wlr_input_device *device) { - struct roots_device_config *d_config; - wl_list_for_each(d_config, &config->devices, link) { - if (strcmp(d_config->name, device->name) == 0) { - return d_config; - } - } - - return NULL; -} - -struct roots_cursor_config *roots_config_get_cursor(struct roots_config *config, - const char *seat_name) { - if (seat_name == NULL) { - seat_name = ROOTS_CONFIG_DEFAULT_SEAT_NAME; - } - - struct roots_cursor_config *cc; - wl_list_for_each(cc, &config->cursors, link) { - if (strcmp(cc->seat, seat_name) == 0) { - return cc; - } - } - return NULL; } diff -Nru phoc-0.6.0/src/settings.h phoc-0.8.0/src/settings.h --- phoc-0.6.0/src/settings.h 2021-01-04 19:46:36.000000000 +0000 +++ phoc-0.8.0/src/settings.h 2021-07-10 00:06:41.000000000 +0000 @@ -29,28 +29,6 @@ struct wl_list modes; }; -struct roots_device_config { - char *name; - char *seat; - bool tap_enabled; - struct wl_list link; -}; - -struct roots_cursor_config { - char *seat; - char *theme; - char *default_image; - struct wl_list link; -}; - -struct roots_switch_config { - char *name; - enum wlr_switch_type switch_type; - enum wlr_switch_state switch_state; - char *command; - struct wl_list link; -}; - struct roots_config { bool xwayland; bool xwayland_lazy; @@ -58,9 +36,6 @@ PhocKeybindings *keybindings; struct wl_list outputs; - struct wl_list devices; - struct wl_list cursors; - struct wl_list switches; char *config_path; }; @@ -83,13 +58,6 @@ struct wlr_output *output); /** - * Get configuration for the device. If the device is not configured, returns - * NULL. - */ -struct roots_device_config *roots_config_get_device(struct roots_config *config, - struct wlr_input_device *device); - -/** * Get configuration for the keyboard. If the keyboard is not configured, * returns NULL. A NULL device returns the default config for keyboards. */ diff -Nru phoc-0.6.0/src/switch.c phoc-0.8.0/src/switch.c --- phoc-0.6.0/src/switch.c 2021-01-04 19:46:36.000000000 +0000 +++ phoc-0.8.0/src/switch.c 2021-07-10 00:06:41.000000000 +0000 @@ -8,19 +8,8 @@ void roots_switch_handle_toggle(struct roots_switch *switch_device, struct wlr_event_switch_toggle *event) { - PhocServer *server = phoc_server_get_default (); - struct wl_list *bound_switches = - &server->config->switches; - struct roots_switch_config *sc; - wl_list_for_each(sc, bound_switches, link) { - if ((sc->name != NULL && strcmp(event->device->name, sc->name) != 0) && - (sc->name == NULL && event->switch_type != sc->switch_type)) { - continue; - } - if (sc->switch_state != WLR_SWITCH_STATE_TOGGLE && - event->switch_state != sc->switch_state) { - continue; - } - g_warning ("Unhandled switch event %s", sc->name); - } + g_debug ("Switch %s, type: %d, state: %d", + event->device->name, + event->switch_type, + event->switch_state); } diff -Nru phoc-0.6.0/src/text_input.c phoc-0.8.0/src/text_input.c --- phoc-0.6.0/src/text_input.c 2021-01-04 19:46:36.000000000 +0000 +++ phoc-0.8.0/src/text_input.c 2021-07-10 00:06:41.000000000 +0000 @@ -71,6 +71,7 @@ static void text_input_set_pending_focused_surface( struct roots_text_input *text_input, struct wlr_surface *surface) { text_input_clear_pending_focused_surface(text_input); + g_assert(surface); text_input->pending_focused_surface = surface; wl_signal_add(&surface->events.destroy, &text_input->pending_focused_surface_destroy); @@ -126,27 +127,14 @@ // TODO: pass intent, display popup size } -static struct roots_text_input *text_input_to_roots( - struct roots_input_method_relay *relay, - struct wlr_text_input_v3 *text_input) { - struct roots_text_input *roots_text_input = NULL; - wl_list_for_each(roots_text_input, &relay->text_inputs, link) { - if (roots_text_input->input == text_input) { - return roots_text_input; - } - } - return NULL; -} - static void handle_text_input_enable(struct wl_listener *listener, void *data) { - struct roots_input_method_relay *relay = wl_container_of(listener, relay, - text_input_enable); + struct roots_text_input *text_input = wl_container_of(listener, text_input, + enable); + struct roots_input_method_relay *relay = text_input->relay; if (relay->input_method == NULL) { wlr_log(WLR_INFO, "Enabling text input when input method is gone"); return; } - struct roots_text_input *text_input = text_input_to_roots(relay, - (struct wlr_text_input_v3*)data); // relay_send_im_done protects from receiving unfocussed done, // but activate must be prevented too. // TODO: when enter happens? @@ -159,10 +147,9 @@ static void handle_text_input_commit(struct wl_listener *listener, void *data) { - struct roots_input_method_relay *relay = wl_container_of(listener, relay, - text_input_commit); - struct roots_text_input *text_input = text_input_to_roots(relay, - (struct wlr_text_input_v3*)data); + struct roots_text_input *text_input = wl_container_of(listener, text_input, + commit); + struct roots_input_method_relay *relay = text_input->relay; if (!text_input->input->current_enabled) { wlr_log(WLR_INFO, "Inactive text input tried to commit an update"); return; @@ -192,24 +179,26 @@ static void handle_text_input_disable(struct wl_listener *listener, void *data) { - struct roots_input_method_relay *relay = wl_container_of(listener, relay, - text_input_disable); - struct roots_text_input *text_input = text_input_to_roots(relay, - (struct wlr_text_input_v3*)data); + struct roots_text_input *text_input = wl_container_of(listener, text_input, + disable); + struct roots_input_method_relay *relay = text_input->relay; relay_disable_text_input(relay, text_input); } static void handle_text_input_destroy(struct wl_listener *listener, void *data) { - struct roots_input_method_relay *relay = wl_container_of(listener, relay, - text_input_destroy); - struct roots_text_input *text_input = text_input_to_roots(relay, - (struct wlr_text_input_v3*)data); + struct roots_text_input *text_input = wl_container_of(listener, text_input, + destroy); + struct roots_input_method_relay *relay = text_input->relay; if (text_input->input->current_enabled) { relay_disable_text_input(relay, text_input); } text_input_clear_pending_focused_surface(text_input); + wl_list_remove(&text_input->commit.link); + wl_list_remove(&text_input->destroy.link); + wl_list_remove(&text_input->disable.link); + wl_list_remove(&text_input->enable.link); wl_list_remove(&text_input->link); text_input->input = NULL; free(text_input); @@ -221,7 +210,7 @@ pending_focused_surface_destroy); struct wlr_surface *surface = data; assert(text_input->pending_focused_surface == surface); - text_input->pending_focused_surface = NULL; + text_input_clear_pending_focused_surface(text_input); } struct roots_text_input *roots_text_input_create( @@ -234,17 +223,17 @@ input->input = text_input; input->relay = relay; - wl_signal_add(&text_input->events.enable, &relay->text_input_enable); - relay->text_input_enable.notify = handle_text_input_enable; + wl_signal_add(&text_input->events.enable, &input->enable); + input->enable.notify = handle_text_input_enable; - wl_signal_add(&text_input->events.commit, &relay->text_input_commit); - relay->text_input_commit.notify = handle_text_input_commit; + wl_signal_add(&text_input->events.commit, &input->commit); + input->commit.notify = handle_text_input_commit; - wl_signal_add(&text_input->events.disable, &relay->text_input_disable); - relay->text_input_disable.notify = handle_text_input_disable; + wl_signal_add(&text_input->events.disable, &input->disable); + input->disable.notify = handle_text_input_disable; - wl_signal_add(&text_input->events.destroy, &relay->text_input_destroy); - relay->text_input_destroy.notify = handle_text_input_destroy; + wl_signal_add(&text_input->events.destroy, &input->destroy); + input->destroy.notify = handle_text_input_destroy; input->pending_focused_surface_destroy.notify = handle_pending_focused_surface_destroy; @@ -316,6 +305,11 @@ &relay->input_method_new); } +void roots_input_method_relay_destroy(struct roots_input_method_relay *relay) { + wl_list_remove(&relay->text_input_new.link); + wl_list_remove(&relay->input_method_new.link); +} + void roots_input_method_relay_set_focus(struct roots_input_method_relay *relay, struct wlr_surface *surface) { struct roots_text_input *text_input; diff -Nru phoc-0.6.0/src/text_input.h phoc-0.8.0/src/text_input.h --- phoc-0.6.0/src/text_input.h 2021-01-04 19:46:36.000000000 +0000 +++ phoc-0.8.0/src/text_input.h 2021-07-10 00:06:41.000000000 +0000 @@ -25,10 +25,6 @@ struct wlr_input_method_v2 *input_method; // doesn't have to be present struct wl_listener text_input_new; - struct wl_listener text_input_enable; - struct wl_listener text_input_commit; - struct wl_listener text_input_disable; - struct wl_listener text_input_destroy; struct wl_listener input_method_new; struct wl_listener input_method_commit; @@ -47,11 +43,17 @@ struct wl_list link; struct wl_listener pending_focused_surface_destroy; + struct wl_listener enable; + struct wl_listener commit; + struct wl_listener disable; + struct wl_listener destroy; }; void roots_input_method_relay_init(struct roots_seat *seat, struct roots_input_method_relay *relay); +void roots_input_method_relay_destroy(struct roots_input_method_relay *relay); + // Updates currently focused surface. Surface must belong to the same seat. void roots_input_method_relay_set_focus(struct roots_input_method_relay *relay, struct wlr_surface *surface); diff -Nru phoc-0.6.0/src/view.c phoc-0.8.0/src/view.c --- phoc-0.6.0/src/view.c 2021-01-04 19:46:36.000000000 +0000 +++ phoc-0.8.0/src/view.c 2021-07-10 00:06:41.000000000 +0000 @@ -199,8 +199,10 @@ return; /* backup window state */ - view->saved.x = view->box.x; - view->saved.y = view->box.y; + struct wlr_box geom; + view_get_geometry(view, &geom); + view->saved.x = view->box.x + geom.x * view->scale; + view->saved.y = view->box.y + geom.y * view->scale; view->saved.width = view->box.width; view->saved.height = view->box.height; } @@ -223,9 +225,16 @@ view_update_output(view, &before); } +void +view_appear_activated (struct roots_view *view, bool activated) +{ + if (view->impl->activate) + view->impl->activate (view, activated); +} + void view_activate(struct roots_view *view, bool activate) { - if (view->impl->activate) { - view->impl->activate(view, activate); + if (!view->desktop->maximize) { + view_appear_activated(view, activate); } if (view->toplevel_handle) { @@ -286,15 +295,15 @@ output_y); } -void view_arrange_maximized(struct roots_view *view) { - if (view->fullscreen_output != NULL) { +void view_arrange_maximized(struct roots_view *view, struct wlr_output *output) { + if (view->fullscreen_output) return; - } - struct wlr_output *output = view_get_output(view); - if (!output) { + if (!output) + output = view_get_output(view); + + if (!output) return; - } PhocOutput *phoc_output = output->data; struct wlr_box *output_box = @@ -308,13 +317,15 @@ } void -view_arrange_tiled (struct roots_view *view) +view_arrange_tiled (struct roots_view *view, struct wlr_output *output) { - struct wlr_output *output = view_get_output (view); - if (!output) + if (view->fullscreen_output) return; - if (view->fullscreen_output) + if (!output) + output = view_get_output(view); + + if (!output) return; PhocOutput *phoc_output = output->data; @@ -359,8 +370,12 @@ return false; } -void view_maximize(struct roots_view *view) { - if (view_is_maximized (view) || view->fullscreen_output != NULL) { +void view_maximize(struct roots_view *view, struct wlr_output *output) { + if (view_is_maximized (view) && view_get_output(view) == output) { + return; + } + + if (view->fullscreen_output != NULL) { return; } @@ -375,7 +390,7 @@ view_save (view); view->state = PHOC_VIEW_STATE_MAXIMIZED; - view_arrange_maximized(view); + view_arrange_maximized(view, output); } /* @@ -385,7 +400,7 @@ view_auto_maximize(struct roots_view *view) { if (want_auto_maximize (view)) - view_maximize (view); + view_maximize (view, NULL); } void @@ -397,8 +412,11 @@ if (want_auto_maximize (view)) return; + struct wlr_box geom; + view_get_geometry(view, &geom); + view->state = PHOC_VIEW_STATE_NORMAL; - view_move_resize (view, view->saved.x, view->saved.y, + view_move_resize (view, view->saved.x - geom.x * view->scale, view->saved.y - geom.y * view->scale, view->saved.width, view->saved.height); if (view->toplevel_handle) @@ -425,6 +443,9 @@ } } + struct wlr_box view_geom; + view_get_geometry(view, &view_geom); + if (fullscreen) { if (output == NULL) { output = view_get_output(view); @@ -455,17 +476,18 @@ } if (was_fullscreen && !fullscreen) { - phoc_output_damage_whole(view->fullscreen_output); - + PhocOutput *phoc_output = view->fullscreen_output; view->fullscreen_output->fullscreen_view = NULL; view->fullscreen_output = NULL; + phoc_output_damage_whole(phoc_output); + if (view->state == PHOC_VIEW_STATE_MAXIMIZED) { - view_arrange_maximized (view); + view_arrange_maximized (view, phoc_output->wlr_output); } else if (view->state == PHOC_VIEW_STATE_TILED) { - view_arrange_tiled (view); + view_arrange_tiled (view, phoc_output->wlr_output); } else { - view_move_resize(view, view->saved.x, view->saved.y, + view_move_resize(view, view->saved.x - view_geom.x * view->scale, view->saved.y - view_geom.y * view->scale, view->saved.width, view->saved.height); } @@ -514,19 +536,20 @@ view->saved.x = x; view->saved.y = y; - view_move(view, x, y); if (view_is_maximized (view)) { - view_arrange_maximized (view); + view_arrange_maximized (view, new_output); } else if (view_is_tiled (view)) { - view_arrange_tiled (view); + view_arrange_tiled (view, new_output); + } else { + view_move(view, x, y); } return true; } void -view_tile(struct roots_view *view, PhocViewTileDirection direction) +view_tile(struct roots_view *view, PhocViewTileDirection direction, struct wlr_output *output) { if (view->fullscreen_output) return; @@ -539,7 +562,7 @@ view->state = PHOC_VIEW_STATE_TILED; view->tile_direction = direction; - view_arrange_tiled (view); + view_arrange_tiled (view, output); } bool view_center(struct roots_view *view) { @@ -772,9 +795,9 @@ } if (view->scale != oldscale) { if (view_is_maximized(view)) { - view_arrange_maximized(view); + view_arrange_maximized(view, NULL); } else if (view_is_tiled(view)) { - view_arrange_tiled(view); + view_arrange_tiled(view, NULL); } else { view_center(view); } @@ -797,14 +820,19 @@ wl_signal_add(&view->wlr_surface->events.new_subsurface, &view->new_subsurface); - if (view->desktop->maximize && !wl_list_empty(&view->desktop->views)) { - // mapping a new stack may make the old stack disappear, so damage its area - struct roots_view *top_view = wl_container_of(view->desktop->views.next, view, link); - while (top_view) { - view_damage_whole(top_view); - top_view = top_view->parent; + if (view->desktop->maximize) { + view_appear_activated(view, true); + + if (!wl_list_empty(&view->desktop->views)) { + // mapping a new stack may make the old stack disappear, so damage its area + struct roots_view *top_view = wl_container_of(view->desktop->views.next, view, link); + while (top_view) { + view_damage_whole(top_view); + top_view = top_view->parent; + } } } + wl_list_insert(&view->desktop->views, &view->link); view_damage_whole(view); phoc_input_update_cursor_focus(server->input); @@ -994,7 +1022,7 @@ toplevel_handle_request_maximize); struct wlr_foreign_toplevel_handle_v1_maximized_event *event = data; if (event->maximized) { - view_maximize(view); + view_maximize(view, NULL); } else { view_restore(view); } diff -Nru phoc-0.6.0/src/view.h phoc-0.8.0/src/view.h --- phoc-0.6.0/src/view.h 2021-01-04 19:46:36.000000000 +0000 +++ phoc-0.8.0/src/view.h 2021-07-10 00:06:41.000000000 +0000 @@ -109,6 +109,8 @@ struct wlr_xdg_surface *xdg_surface; + struct wlr_box saved_geometry; + struct wl_listener destroy; struct wl_listener new_popup; struct wl_listener map; @@ -193,6 +195,7 @@ void view_init(struct roots_view *view, const struct roots_view_interface *impl, enum roots_view_type type, PhocDesktop *desktop); void view_destroy(struct roots_view *view); +void view_appear_activated(struct roots_view *view, bool activated); void view_activate(struct roots_view *view, bool activate); void view_apply_damage(struct roots_view *view); void view_damage_whole(struct roots_view *view); @@ -204,8 +207,8 @@ void view_initial_focus(struct roots_view *view); void view_map(struct roots_view *view, struct wlr_surface *surface); void view_unmap(struct roots_view *view); -void view_arrange_maximized(struct roots_view *view); -void view_arrange_tiled(struct roots_view *view); +void view_arrange_maximized(struct roots_view *view, struct wlr_output *output); +void view_arrange_tiled(struct roots_view *view, struct wlr_output *output); void view_get_box(const struct roots_view *view, struct wlr_box *box); void view_get_geometry(struct roots_view *view, struct wlr_box *box); void view_move(struct roots_view *view, double x, double y); @@ -214,8 +217,8 @@ void view_move_resize(struct roots_view *view, double x, double y, uint32_t width, uint32_t height); void view_auto_maximize(struct roots_view *view); -void view_tile(struct roots_view *view, PhocViewTileDirection direction); -void view_maximize(struct roots_view *view); +void view_tile(struct roots_view *view, PhocViewTileDirection direction, struct wlr_output *output); +void view_maximize(struct roots_view *view, struct wlr_output *output); void view_restore(struct roots_view *view); void view_set_fullscreen(struct roots_view *view, bool fullscreen, struct wlr_output *output); diff -Nru phoc-0.6.0/src/xdg_shell.c phoc-0.8.0/src/xdg_shell.c --- phoc-0.6.0/src/xdg_shell.c 2021-01-04 19:46:36.000000000 +0000 +++ phoc-0.8.0/src/xdg_shell.c 2021-07-10 00:06:41.000000000 +0000 @@ -356,7 +356,7 @@ } if (surface->toplevel->client_pending.maximized) { - view_maximize(view); + view_maximize(view, NULL); } else { view_restore(view); } @@ -440,6 +440,17 @@ roots_surface->pending_move_resize_configure_serial = 0; } } + + struct wlr_box geometry; + get_geometry(view, &geometry); + if (roots_surface->saved_geometry.x != geometry.x || roots_surface->saved_geometry.y != geometry.y) { + if (!view_is_maximized(view) && !view_is_tiled(view) && !view->fullscreen_output) { + view_update_position(view, + view->box.x + (roots_surface->saved_geometry.x - geometry.x) * view->scale, + view->box.y + (roots_surface->saved_geometry.y - geometry.y) * view->scale); + } + } + roots_surface->saved_geometry = geometry; } static void handle_new_popup(struct wl_listener *listener, void *data) { @@ -458,6 +469,7 @@ get_size(view, &box); view->box.width = box.width; view->box.height = box.height; + get_geometry(view, &roots_xdg_surface->saved_geometry); view_map(view, roots_xdg_surface->xdg_surface->surface); view_setup(view); @@ -508,7 +520,7 @@ view_set_parent(&roots_surface->view, &parent->view); } if (surface->toplevel->client_pending.maximized) { - view_maximize(&roots_surface->view); + view_maximize(&roots_surface->view, NULL); } view_set_fullscreen(&roots_surface->view, surface->toplevel->client_pending.fullscreen, surface->toplevel->client_pending.fullscreen_output); diff -Nru phoc-0.6.0/src/xwayland.c phoc-0.8.0/src/xwayland.c --- phoc-0.6.0/src/xwayland.c 2021-01-04 19:46:36.000000000 +0000 +++ phoc-0.8.0/src/xwayland.c 2021-07-10 00:06:41.000000000 +0000 @@ -257,7 +257,7 @@ bool maximized = xwayland_surface->maximized_vert && xwayland_surface->maximized_horz; if (maximized) { - view_maximize(view); + view_maximize(view, NULL); } else { view_restore(view); } @@ -333,7 +333,7 @@ &roots_surface->surface_commit); if (surface->maximized_horz && surface->maximized_vert) { - view_maximize(view); + view_maximize(view, NULL); } view_auto_maximize(view); diff -Nru phoc-0.6.0/tests/test-phosh.c phoc-0.8.0/tests/test-phosh.c --- phoc-0.6.0/tests/test-phosh.c 2021-01-04 19:46:36.000000000 +0000 +++ phoc-0.8.0/tests/test-phosh.c 2021-07-10 00:06:41.000000000 +0000 @@ -26,12 +26,17 @@ guint32 width, height; } PhocTestThumbnail; +typedef enum { + GRAB_STATUS_FAILED = -1, + GRAB_STATUS_UNKNOWN = 0, + GRAB_STATUS_OK = 1, +} PhocTestGrabStatus; + typedef struct _PhocTestKeyboardEvent { char *title; struct phosh_private_keyboard_event *kbevent; - gboolean test_grab_successful; - gboolean test_grab_unsuccesful; + PhocTestGrabStatus grab_status; } PhocTestKeyboardEvent; static void @@ -196,7 +201,7 @@ g_assert_nonnull (kbevent); g_assert (kbe->kbevent == kbevent); - kbe->test_grab_unsuccesful = TRUE; + kbe->grab_status = GRAB_STATUS_FAILED; } static void @@ -211,7 +216,7 @@ g_assert (kbe->kbevent == kbevent); if (action_id > 0) - kbe->test_grab_successful = TRUE; + kbe->grab_status = GRAB_STATUS_OK; } static const struct phosh_private_keyboard_event_listener keyboard_event_listener = { @@ -235,47 +240,65 @@ return kbe; } +#define RAISE_VOL_KEY "XF86AudioRaiseVolume" + static gboolean test_client_phosh_kbevent_simple (PhocTestClientGlobals *globals, gpointer unused) { PhocTestKeyboardEvent *test1; PhocTestKeyboardEvent *test2; - gchar *test_accelerators[] = { - "XF86AudioLowerVolume", - "XF86AudioRaiseVolume", - "XF86AudioLowerVolume", - "F9", - }; test1 = phoc_test_keyboard_event_new (globals, "test-mediakey-grabbing"); test2 = phoc_test_keyboard_event_new (globals, "test-invalid-grabbing"); - phosh_private_keyboard_event_grab_accelerator_request (test1->kbevent, test_accelerators[0]); - phosh_private_keyboard_event_grab_accelerator_request (test2->kbevent, test_accelerators[3]); + phosh_private_keyboard_event_grab_accelerator_request (test1->kbevent, + "XF86AudioLowerVolume"); + /* Not allowed to bind this one: */ + phosh_private_keyboard_event_grab_accelerator_request (test2->kbevent, + "F9"); + wl_display_dispatch (globals->display); + wl_display_roundtrip (globals->display); + + g_assert_cmpint (test1->grab_status, ==, GRAB_STATUS_OK); + g_assert_cmpint (test2->grab_status, ==, GRAB_STATUS_FAILED); + + test1->grab_status = GRAB_STATUS_UNKNOWN; + test2->grab_status = GRAB_STATUS_UNKNOWN; + + phosh_private_keyboard_event_grab_accelerator_request (test1->kbevent, + RAISE_VOL_KEY); + /* Can't bind same key twice: */ + phosh_private_keyboard_event_grab_accelerator_request (test2->kbevent, + RAISE_VOL_KEY); wl_display_dispatch (globals->display); wl_display_roundtrip (globals->display); - g_assert_true (test1->test_grab_successful); - g_assert_true (test2->test_grab_unsuccesful); + g_assert_cmpint (test1->grab_status, ==, GRAB_STATUS_OK); + g_assert_cmpint (test2->grab_status, ==, GRAB_STATUS_FAILED); - test1->test_grab_successful = FALSE; - test2->test_grab_unsuccesful = FALSE; + test1->grab_status = GRAB_STATUS_UNKNOWN; + test2->grab_status = GRAB_STATUS_UNKNOWN; - phosh_private_keyboard_event_grab_accelerator_request (test1->kbevent, test_accelerators[1]); - phosh_private_keyboard_event_grab_accelerator_request (test2->kbevent, test_accelerators[1]); + /* Allowing to bind a already bound key with an additional accelerator is o.k. */ + phosh_private_keyboard_event_grab_accelerator_request (test1->kbevent, + "" RAISE_VOL_KEY); wl_display_dispatch (globals->display); wl_display_roundtrip (globals->display); - g_assert_true (test1->test_grab_successful); - g_assert_true (test2->test_grab_unsuccesful); + g_assert_cmpint (test1->grab_status, ==, GRAB_STATUS_OK); + g_assert_cmpint (test2->grab_status, ==, GRAB_STATUS_UNKNOWN); - test1->test_grab_successful = FALSE; + test1->grab_status = GRAB_STATUS_UNKNOWN; + test2->grab_status = GRAB_STATUS_UNKNOWN; - phosh_private_keyboard_event_grab_accelerator_request (test1->kbevent, test_accelerators[2]); + /* Binding non existing key must fail */ + phosh_private_keyboard_event_grab_accelerator_request (test2->kbevent, + "does-not-exist"); wl_display_dispatch (globals->display); wl_display_roundtrip (globals->display); - g_assert_true (test1->test_grab_successful); + g_assert_cmpint (test1->grab_status, ==, GRAB_STATUS_UNKNOWN); + g_assert_cmpint (test2->grab_status, ==, GRAB_STATUS_FAILED); phosh_private_keyboard_event_destroy (test1->kbevent); phosh_private_keyboard_event_destroy (test2->kbevent);