Changeset a2e104e in mainline


Ignore:
Timestamp:
2020-03-05T11:23:41Z (5 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
1e4a937
Parents:
338d0935
git-author:
Jiri Svoboda <jiri@…> (2020-03-04 19:23:29)
git-committer:
Jiri Svoboda <jiri@…> (2020-03-05 11:23:41)
Message:

Move windows by dragging decoration

Or dragging anywhere with button 2. Need to add Ctrl/Alt/Shift state
to pos_event_t and change the latter to Alt-drag/Shift-drag.

Location:
uspace
Files:
11 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/display/include/disp_srv.h

    r338d0935 ra2e104e  
    5454        errno_t (*window_create)(void *, display_wnd_params_t *, sysarg_t *);
    5555        errno_t (*window_destroy)(void *, sysarg_t);
     56        errno_t (*window_move_req)(void *, sysarg_t, gfx_coord2_t *);
    5657        errno_t (*window_resize)(void *, sysarg_t, gfx_coord2_t *, gfx_rect_t *);
    5758        errno_t (*get_event)(void *, sysarg_t *, display_wnd_ev_t *);
  • uspace/lib/display/include/display.h

    r338d0935 ra2e104e  
    4949extern errno_t display_window_destroy(display_window_t *);
    5050extern errno_t display_window_get_gc(display_window_t *, gfx_context_t **);
     51extern errno_t display_window_move_req(display_window_t *, gfx_coord2_t *);
    5152extern errno_t display_window_resize(display_window_t *,
    5253    gfx_coord2_t *, gfx_rect_t *);
  • uspace/lib/display/include/ipc/display.h

    r338d0935 ra2e104e  
    4242        DISPLAY_WINDOW_CREATE,
    4343        DISPLAY_WINDOW_DESTROY,
     44        DISPLAY_WINDOW_MOVE_REQ,
    4445        DISPLAY_WINDOW_RESIZE,
    4546        DISPLAY_GET_EVENT
  • uspace/lib/display/src/disp_srv.c

    r338d0935 ra2e104e  
    100100        wnd_id = ipc_get_arg1(icall);
    101101
    102         if (srv->ops->window_create == NULL) {
     102        if (srv->ops->window_destroy == NULL) {
    103103                async_answer_0(icall, ENOTSUP);
    104104                return;
     
    106106
    107107        rc = srv->ops->window_destroy(srv->arg, wnd_id);
     108        async_answer_0(icall, rc);
     109}
     110
     111static void display_window_move_req_srv(display_srv_t *srv, ipc_call_t *icall)
     112{
     113        sysarg_t wnd_id;
     114        ipc_call_t call;
     115        gfx_coord2_t pos;
     116        size_t size;
     117        errno_t rc;
     118
     119        wnd_id = ipc_get_arg1(icall);
     120
     121        if (!async_data_write_receive(&call, &size)) {
     122                async_answer_0(&call, EREFUSED);
     123                async_answer_0(icall, EREFUSED);
     124                return;
     125        }
     126
     127        if (size != sizeof(gfx_coord2_t)) {
     128                async_answer_0(&call, EINVAL);
     129                async_answer_0(icall, EINVAL);
     130                return;
     131        }
     132
     133        rc = async_data_write_finalize(&call, &pos, size);
     134        if (rc != EOK) {
     135                async_answer_0(&call, rc);
     136                async_answer_0(icall, rc);
     137                return;
     138        }
     139
     140        if (srv->ops->window_move_req == NULL) {
     141                async_answer_0(icall, ENOTSUP);
     142                return;
     143        }
     144
     145        rc = srv->ops->window_move_req(srv->arg, wnd_id, &pos);
    108146        async_answer_0(icall, rc);
    109147}
     
    215253                case DISPLAY_WINDOW_DESTROY:
    216254                        display_window_destroy_srv(srv, &call);
     255                        break;
     256                case DISPLAY_WINDOW_MOVE_REQ:
     257                        display_window_move_req_srv(srv, &call);
    217258                        break;
    218259                case DISPLAY_WINDOW_RESIZE:
  • uspace/lib/display/src/display.c

    r338d0935 ra2e104e  
    244244}
    245245
     246/** Request a window move.
     247 *
     248 * Request the display service to initiate a user window move operation
     249 * (i.e. let the user move the window). Used when the client detects
     250 * mouse press on the title bar or such.
     251 *
     252 * @param window Window
     253 * @return EOK on success or an error code
     254 */
     255errno_t display_window_move_req(display_window_t *window, gfx_coord2_t *pos)
     256{
     257        async_exch_t *exch;
     258        aid_t req;
     259        ipc_call_t answer;
     260        errno_t rc;
     261
     262        exch = async_exchange_begin(window->display->sess);
     263        req = async_send_1(exch, DISPLAY_WINDOW_MOVE_REQ, window->id, &answer);
     264        rc = async_data_write_start(exch, (void *)pos, sizeof (gfx_coord2_t));
     265        async_exchange_end(exch);
     266        if (rc != EOK) {
     267                async_forget(req);
     268                return rc;
     269        }
     270
     271        async_wait_for(req, &rc);
     272        if (rc != EOK)
     273                return rc;
     274
     275        return EOK;
     276}
     277
    246278/** Resize display window.
    247279 *
     
    283315 * @param nrect New bounding rectangle
    284316 * @param offs
    285  * @return EOK on success or an error code. In both cases @a window must
    286  *         not be accessed anymore
     317 * @return EOK on success or an error code
    287318 */
    288319errno_t display_window_resize(display_window_t *window, gfx_coord2_t *offs,
  • uspace/lib/display/test/display.c

    r338d0935 ra2e104e  
    5656static errno_t test_window_create(void *, display_wnd_params_t *, sysarg_t *);
    5757static errno_t test_window_destroy(void *, sysarg_t);
     58static errno_t test_window_move_req(void *, sysarg_t, gfx_coord2_t *);
    5859static errno_t test_window_resize(void *, sysarg_t, gfx_coord2_t *,
    5960    gfx_rect_t *);
     
    6566        .window_create = test_window_create,
    6667        .window_destroy = test_window_destroy,
     68        .window_move_req = test_window_move_req,
    6769        .window_resize = test_window_resize,
    6870        .get_event = test_get_event
     
    9496        bool window_destroy_called;
    9597        sysarg_t destroy_wnd_id;
     98
     99        bool window_move_req_called;
     100        sysarg_t move_req_wnd_id;
     101        gfx_coord2_t move_req_pos;
    96102
    97103        bool window_resize_called;
     
    294300}
    295301
     302/** display_window_move_req() with server returning error response works. */
     303PCUT_TEST(window_move_req_failure)
     304{
     305        errno_t rc;
     306        service_id_t sid;
     307        display_t *disp = NULL;
     308        display_wnd_params_t params;
     309        display_window_t *wnd;
     310        test_response_t resp;
     311        gfx_coord2_t pos;
     312
     313        async_set_fallback_port_handler(test_display_conn, &resp);
     314
     315        // FIXME This causes this test to be non-reentrant!
     316        rc = loc_server_register(test_display_server);
     317        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     318
     319        rc = loc_service_register(test_display_svc, &sid);
     320        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     321
     322        rc = display_open(test_display_svc, &disp);
     323        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     324        PCUT_ASSERT_NOT_NULL(disp);
     325
     326        resp.rc = EOK;
     327        display_wnd_params_init(&params);
     328        params.rect.p0.x = 0;
     329        params.rect.p0.y = 0;
     330        params.rect.p0.x = 100;
     331        params.rect.p0.y = 100;
     332
     333        rc = display_window_create(disp, &params, &test_display_wnd_cb,
     334            (void *) &resp, &wnd);
     335        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     336        PCUT_ASSERT_NOT_NULL(wnd);
     337
     338        resp.rc = EIO;
     339        resp.window_move_req_called = false;
     340
     341        pos.x = 42;
     342        pos.y = 43;
     343
     344        rc = display_window_move_req(wnd, &pos);
     345        PCUT_ASSERT_TRUE(resp.window_move_req_called);
     346        PCUT_ASSERT_ERRNO_VAL(resp.rc, rc);
     347        PCUT_ASSERT_INT_EQUALS(wnd->id, resp.move_req_wnd_id);
     348        PCUT_ASSERT_INT_EQUALS(pos.x, resp.move_req_pos.x);
     349        PCUT_ASSERT_INT_EQUALS(pos.y, resp.move_req_pos.y);
     350
     351        display_window_destroy(wnd);
     352        display_close(disp);
     353        rc = loc_service_unregister(sid);
     354        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     355}
     356
     357/** display_window_move_req() with server returning success response works. */
     358PCUT_TEST(window_move_req_success)
     359{
     360        errno_t rc;
     361        service_id_t sid;
     362        display_t *disp = NULL;
     363        display_wnd_params_t params;
     364        display_window_t *wnd;
     365        test_response_t resp;
     366        gfx_coord2_t pos;
     367
     368        async_set_fallback_port_handler(test_display_conn, &resp);
     369
     370        // FIXME This causes this test to be non-reentrant!
     371        rc = loc_server_register(test_display_server);
     372        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     373
     374        rc = loc_service_register(test_display_svc, &sid);
     375        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     376
     377        rc = display_open(test_display_svc, &disp);
     378        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     379        PCUT_ASSERT_NOT_NULL(disp);
     380
     381        resp.rc = EOK;
     382        display_wnd_params_init(&params);
     383        params.rect.p0.x = 0;
     384        params.rect.p0.y = 0;
     385        params.rect.p0.x = 100;
     386        params.rect.p0.y = 100;
     387
     388        rc = display_window_create(disp, &params, &test_display_wnd_cb,
     389            (void *) &resp, &wnd);
     390        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     391        PCUT_ASSERT_NOT_NULL(wnd);
     392
     393        resp.rc = EOK;
     394        resp.window_move_req_called = false;
     395
     396        pos.x = 42;
     397        pos.y = 43;
     398
     399        rc = display_window_move_req(wnd, &pos);
     400        PCUT_ASSERT_TRUE(resp.window_move_req_called);
     401        PCUT_ASSERT_ERRNO_VAL(resp.rc, rc);
     402        PCUT_ASSERT_INT_EQUALS(wnd->id, resp.move_req_wnd_id);
     403        PCUT_ASSERT_INT_EQUALS(pos.x, resp.move_req_pos.x);
     404        PCUT_ASSERT_INT_EQUALS(pos.y, resp.move_req_pos.y);
     405
     406        display_window_destroy(wnd);
     407        display_close(disp);
     408        rc = loc_service_unregister(sid);
     409        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     410}
     411
    296412/** display_window_resize() with server returning error response works. */
    297413PCUT_TEST(window_resize_failure)
     
    10131129}
    10141130
     1131static errno_t test_window_move_req(void *arg, sysarg_t wnd_id,
     1132    gfx_coord2_t *pos)
     1133{
     1134        test_response_t *resp = (test_response_t *) arg;
     1135
     1136        resp->window_move_req_called = true;
     1137        resp->move_req_wnd_id = wnd_id;
     1138        resp->move_req_pos = *pos;
     1139        return resp->rc;
     1140}
     1141
    10151142static errno_t test_window_resize(void *arg, sysarg_t wnd_id,
    10161143    gfx_coord2_t *offs, gfx_rect_t *nrect)
  • uspace/lib/gui/window.c

    r338d0935 ra2e104e  
    272272static void root_handle_position_event(widget_t *widget, pos_event_t event)
    273273{
     274        gfx_coord2_t pos;
     275
    274276        if (widget->window->is_decorated) {
    275277                sysarg_t width = widget->width;
     
    339341                        flags |= GF_MOVE_X;
    340342                        flags |= GF_MOVE_Y;
    341                         //win_grab(widget->window->osess, event.pos_id, flags);
     343                        pos.x = event.hpos;
     344                        pos.y = event.vpos;
     345                        (void) display_window_move_req(widget->window->dwindow,
     346                            &pos);
    342347                } else {
    343348                        list_foreach(widget->children, link, widget_t, child) {
  • uspace/srv/hid/display/dsops.c

    r338d0935 ra2e104e  
    4646static errno_t disp_window_create(void *, display_wnd_params_t *, sysarg_t *);
    4747static errno_t disp_window_destroy(void *, sysarg_t);
     48static errno_t disp_window_move_req(void *, sysarg_t, gfx_coord2_t *);
    4849static errno_t disp_window_resize(void *, sysarg_t, gfx_coord2_t *,
    4950    gfx_rect_t *);
     
    5354        .window_create = disp_window_create,
    5455        .window_destroy = disp_window_destroy,
     56        .window_move_req = disp_window_move_req,
    5557        .window_resize = disp_window_resize,
    5658        .get_event = disp_get_event
     
    102104}
    103105
     106static errno_t disp_window_move_req(void *arg, sysarg_t wnd_id,
     107    gfx_coord2_t *pos)
     108{
     109        ds_client_t *client = (ds_client_t *) arg;
     110        ds_window_t *wnd;
     111
     112        wnd = ds_client_find_window(client, wnd_id);
     113        if (wnd == NULL)
     114                return ENOENT;
     115
     116        log_msg(LVL_NOTE, LVL_DEBUG, "disp_window_move_req()");
     117        ds_window_move_req(wnd, pos);
     118        return EOK;
     119}
     120
    104121static errno_t disp_window_resize(void *arg, sysarg_t wnd_id,
    105122    gfx_coord2_t *offs, gfx_rect_t *nbound)
  • uspace/srv/hid/display/test/window.c

    r338d0935 ra2e104e  
    201201        PCUT_ASSERT_INT_EQUALS(dsw_idle, wnd->state);
    202202
     203        wnd->dpos.x = 10;
     204        wnd->dpos.y = 10;
     205
    203206        event.type = POS_PRESS;
     207        event.btn_num = 2;
    204208        event.hpos = 10;
    205209        event.vpos = 10;
     
    216220
    217221        PCUT_ASSERT_INT_EQUALS(dsw_moving, wnd->state);
    218         PCUT_ASSERT_INT_EQUALS(wnd->dpos.x, 1);
    219         PCUT_ASSERT_INT_EQUALS(wnd->dpos.y, 2);
     222        PCUT_ASSERT_INT_EQUALS(11, wnd->dpos.x);
     223        PCUT_ASSERT_INT_EQUALS(12, wnd->dpos.y);
    220224
    221225        event.type = POS_RELEASE;
     
    227231
    228232        PCUT_ASSERT_INT_EQUALS(dsw_idle, wnd->state);
    229         PCUT_ASSERT_INT_EQUALS(wnd->dpos.x, 3);
    230         PCUT_ASSERT_INT_EQUALS(wnd->dpos.y, 4);
     233        PCUT_ASSERT_INT_EQUALS(13, wnd->dpos.x);
     234        PCUT_ASSERT_INT_EQUALS(14, wnd->dpos.y);
     235
     236        ds_window_destroy(wnd);
     237        ds_client_destroy(client);
     238        ds_display_destroy(disp);
     239}
     240
     241/** Test ds_window_move_req() */
     242PCUT_TEST(window_move_req)
     243{
     244        gfx_context_t *gc;
     245        ds_display_t *disp;
     246        ds_client_t *client;
     247        ds_window_t *wnd;
     248        display_wnd_params_t params;
     249        gfx_coord2_t pos;
     250        errno_t rc;
     251
     252        rc = gfx_context_new(&dummy_ops, NULL, &gc);
     253        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     254
     255        rc = ds_display_create(gc, &disp);
     256        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     257
     258        rc = ds_client_create(disp, NULL, NULL, &client);
     259        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     260
     261        display_wnd_params_init(&params);
     262        params.rect.p0.x = params.rect.p0.y = 0;
     263        params.rect.p1.x = params.rect.p1.y = 1;
     264
     265        rc = ds_window_create(client, &params, &wnd);
     266        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     267
     268        PCUT_ASSERT_INT_EQUALS(dsw_idle, wnd->state);
     269
     270        pos.x = 42;
     271        pos.y = 43;
     272        ds_window_move_req(wnd, &pos);
     273
     274        PCUT_ASSERT_INT_EQUALS(dsw_moving, wnd->state);
     275        PCUT_ASSERT_INT_EQUALS(pos.x, wnd->orig_pos.x);
     276        PCUT_ASSERT_INT_EQUALS(pos.y, wnd->orig_pos.y);
    231277
    232278        ds_window_destroy(wnd);
  • uspace/srv/hid/display/window.c

    r338d0935 ra2e104e  
    436436}
    437437
     438/** Start moving a window, detected by client.
     439 *
     440 * @param wnd Window
     441 * @param pos Position where the pointer was when the move started
     442 *            relative to the window
     443 * @param event Button press event
     444 */
     445void ds_window_move_req(ds_window_t *wnd, gfx_coord2_t *pos)
     446{
     447        log_msg(LOG_DEFAULT, LVL_DEBUG, "ds_window_move_req (%d, %d)",
     448            (int) pos->x, (int) pos->y);
     449
     450        if (wnd->state != dsw_idle)
     451                return;
     452
     453        gfx_coord2_add(&wnd->dpos, pos, &wnd->orig_pos);
     454        wnd->state = dsw_moving;
     455}
     456
    438457/** Start moving a window by mouse drag.
    439458 *
     
    446465            (int) event->hpos, (int) event->vpos);
    447466
    448         assert(wnd->state == dsw_idle);
     467        if (wnd->state != dsw_idle)
     468                return;
    449469
    450470        wnd->orig_pos.x = event->hpos;
     
    467487            (int) event->hpos, (int) event->vpos);
    468488
    469         assert(wnd->state == dsw_moving);
     489        if (wnd->state != dsw_moving)
     490                return;
     491
    470492        pos.x = event->hpos;
    471493        pos.y = event->vpos;
     
    497519            (int) event->hpos, (int) event->vpos);
    498520
     521        if (wnd->state != dsw_moving)
     522                return;
     523
    499524        gfx_rect_translate(&wnd->dpos, &wnd->rect, &drect);
    500525
     
    505530        }
    506531
    507         assert(wnd->state == dsw_moving);
    508532        pos.x = event->hpos;
    509533        pos.y = event->vpos;
     
    559583{
    560584        pos_event_t tevent;
     585        gfx_coord2_t pos;
     586        gfx_rect_t drect;
     587        bool inside;
    561588
    562589        log_msg(LOG_DEFAULT, LVL_DEBUG,
     
    564591            (int) event->hpos, (int) event->vpos);
    565592
    566         if (event->type == POS_PRESS) {
    567                 if (wnd->state == dsw_idle)
    568                         ds_window_start_move(wnd, event);
    569         }
    570 
    571         if (event->type == POS_RELEASE) {
    572                 if (wnd->state == dsw_moving)
    573                         ds_window_finish_move(wnd, event);
    574         }
    575 
    576         if (event->type == POS_UPDATE) {
    577                 if (wnd->state == dsw_moving)
    578                         ds_window_update_move(wnd, event);
    579         }
     593        pos.x = event->hpos;
     594        pos.y = event->vpos;
     595        gfx_rect_translate(&wnd->dpos, &wnd->rect, &drect);
     596        inside = gfx_pix_inside_rect(&pos, &drect);
     597
     598        if (event->type == POS_PRESS && event->btn_num == 2 && inside)
     599                ds_window_start_move(wnd, event);
     600
     601        if (event->type == POS_RELEASE)
     602                ds_window_finish_move(wnd, event);
     603
     604        if (event->type == POS_UPDATE)
     605                ds_window_update_move(wnd, event);
    580606
    581607        /* Transform event coordinates to window-local */
  • uspace/srv/hid/display/window.h

    r338d0935 ra2e104e  
    5858extern errno_t ds_window_post_focus_event(ds_window_t *);
    5959extern errno_t ds_window_post_unfocus_event(ds_window_t *);
     60extern void ds_window_move_req(ds_window_t *wnd, gfx_coord2_t *);
    6061
    6162#endif
Note: See TracChangeset for help on using the changeset viewer.