Fork us on GitHub Follow us on Facebook Follow us on Twitter

Changeset 6828a56 in mainline


Ignore:
Timestamp:
2023-01-19T13:51:14Z (2 weeks ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
master
Children:
5d380b6
Parents:
3be5366
git-author:
Jiri Svoboda <jiri@…> (2023-01-19 19:50:50)
git-committer:
Jiri Svoboda <jiri@…> (2023-01-19 13:51:14)
Message:

Avoid two seats fighting when moving/resizing a window

When two seats have focus on the same window, both pointer's movements
would be delivered to it. Make sure only the seat which started the
move or resize operation affects the operation, otherwise they fight
over it.

Location:
uspace/srv/hid/display
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • uspace/srv/hid/display/test/window.c

    r3be5366 r6828a56  
    3636#include "../client.h"
    3737#include "../display.h"
     38#include "../idevcfg.h"
    3839#include "../seat.h"
    3940#include "../window.h"
     
    12731274}
    12741275
     1276/** ds_window_orig_seat() correctly compares seats */
     1277PCUT_TEST(window_orig_seat)
     1278{
     1279        gfx_context_t *gc;
     1280        ds_display_t *disp;
     1281        ds_client_t *client;
     1282        ds_seat_t *seat0;
     1283        ds_seat_t *seat1;
     1284        sysarg_t devid0;
     1285        sysarg_t devid1;
     1286        ds_idevcfg_t *cfg0;
     1287        ds_idevcfg_t *cfg1;
     1288        ds_window_t *wnd;
     1289        display_wnd_params_t params;
     1290        errno_t rc;
     1291
     1292        rc = gfx_context_new(&dummy_ops, NULL, &gc);
     1293        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     1294
     1295        rc = ds_display_create(gc, df_none, &disp);
     1296        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     1297
     1298        rc = ds_client_create(disp, NULL, NULL, &client);
     1299        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     1300
     1301        rc = ds_seat_create(disp, "Alice", &seat0);
     1302        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     1303
     1304        rc = ds_seat_create(disp, "Bob", &seat1);
     1305        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     1306
     1307        display_wnd_params_init(&params);
     1308        params.rect.p0.x = params.rect.p0.y = 0;
     1309        params.rect.p1.x = params.rect.p1.y = 1;
     1310
     1311        rc = ds_window_create(client, &params, &wnd);
     1312        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     1313
     1314        devid0 = 42;
     1315        devid1 = 43;
     1316
     1317        rc = ds_idevcfg_create(disp, devid0, seat0, &cfg0);
     1318        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     1319
     1320        rc = ds_idevcfg_create(disp, devid1, seat1, &cfg1);
     1321        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     1322
     1323        wnd->state = dsw_moving;
     1324        wnd->orig_pos_id = devid0;
     1325
     1326        PCUT_ASSERT_TRUE(ds_window_orig_seat(wnd, devid0));
     1327        PCUT_ASSERT_FALSE(ds_window_orig_seat(wnd, devid1));
     1328
     1329        ds_idevcfg_destroy(cfg0);
     1330        ds_idevcfg_destroy(cfg1);
     1331        ds_window_destroy(wnd);
     1332        ds_seat_destroy(seat0);
     1333        ds_seat_destroy(seat1);
     1334        ds_client_destroy(client);
     1335        ds_display_destroy(disp);
     1336}
     1337
    12751338static errno_t dummy_set_color(void *arg, gfx_color_t *color)
    12761339{
  • uspace/srv/hid/display/window.c

    r3be5366 r6828a56  
    656656
    657657        if (event->type == POS_RELEASE) {
    658                 if (wnd->state == dsw_moving) {
     658                /* Finish move/resize if they were started by the same seat */
     659                if (wnd->state == dsw_moving &&
     660                    ds_window_orig_seat(wnd, pos_id)) {
    659661                        ds_window_finish_move(wnd, &pos);
    660662                        return EOK;
    661663                }
    662664
    663                 if (wnd->state == dsw_resizing) {
     665                if (wnd->state == dsw_resizing &&
     666                    ds_window_orig_seat(wnd, pos_id)) {
    664667                        ds_window_finish_resize(wnd, &pos);
    665668                        return EOK;
     
    668671
    669672        if (event->type == POS_UPDATE) {
    670                 if (wnd->state == dsw_moving) {
     673                /* Update move/resize if they were started by the same seat */
     674                if (wnd->state == dsw_moving &&
     675                    ds_window_orig_seat(wnd, pos_id)) {
    671676                        ds_window_update_move(wnd, &pos);
    672677                        return EOK;
    673678                }
    674679
    675                 if (wnd->state == dsw_resizing) {
     680                if (wnd->state == dsw_resizing &&
     681                    ds_window_orig_seat(wnd, pos_id)) {
    676682                        ds_window_update_resize(wnd, &pos);
    677683                        return EOK;
     
    11251131}
    11261132
     1133/** Determine if input device belongs to the same seat as the original device.
     1134 *
     1135 * Compare the seat ownning @a idev_id with the seat owning @a wnd->orig_pos_id
     1136 * (the device that started the window move or resize).
     1137 *
     1138 * This is used to make sure that, when two seats focus the same window,
     1139 * only devices owned by the seat that started the resize or move can
     1140 * affect it. Otherwise moving the other pointer(s) would disrupt the
     1141 * resize or move operation.
     1142 *
     1143 * @param wnd Window (that is currently being resized or moved)
     1144 * @param idev_id Input device ID
     1145 * @return @c true iff idev_id is owned by the same seat as the input
     1146 *         device that started the resize or move
     1147 */
     1148bool ds_window_orig_seat(ds_window_t *wnd, sysarg_t idev_id)
     1149{
     1150        ds_seat_t *orig_seat;
     1151        ds_seat_t *seat;
     1152
     1153        /* Window must be in state such that wnd->orig_pos_id is valid */
     1154        assert(wnd->state == dsw_moving || wnd->state == dsw_resizing);
     1155
     1156        orig_seat = ds_display_seat_by_idev(wnd->display, wnd->orig_pos_id);
     1157        seat = ds_display_seat_by_idev(wnd->display, idev_id);
     1158
     1159        return seat == orig_seat;
     1160}
     1161
    11271162/** Window memory GC invalidate callback.
    11281163 *
  • uspace/srv/hid/display/window.h

    r3be5366 r6828a56  
    8080extern ds_window_t *ds_window_find_alt(ds_window_t *, display_wnd_flags_t);
    8181extern void ds_window_unfocus(ds_window_t *);
     82extern bool ds_window_orig_seat(ds_window_t *, sysarg_t);
    8283
    8384#endif
Note: See TracChangeset for help on using the changeset viewer.