Changeset 0da03df in mainline


Ignore:
Timestamp:
2020-12-10T10:27:07Z (4 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
442210e
Parents:
08f345f
git-author:
Jiri Svoboda <jiri@…> (2020-12-09 18:26:57)
git-committer:
Jiri Svoboda <jiri@…> (2020-12-10 10:27:07)
Message:

Distinguish between focus switching and evacuation

It's the same thing if there are at least two windows. With just
one window, switching focus should do nothing. Evacuation should
lead to no window being focused. (Fixes crash when pressing
Alt-Shift/Ctrl-Shift with just one window left).

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

Legend:

Unmodified
Added
Removed
  • uspace/srv/hid/display/seat.c

    r08f345f r0da03df  
    128128}
    129129
     130/** Switch focus to another window.
     131 *
     132 * @param seat Seat
     133 * @param wnd Window to evacuate focus from
     134 */
     135void ds_seat_switch_focus(ds_seat_t *seat)
     136{
     137        ds_window_t *nwnd;
     138
     139        if (seat->focus != NULL)
     140                nwnd = ds_display_prev_window(seat->focus);
     141        else
     142                nwnd = NULL;
     143
     144        if (nwnd == NULL)
     145                nwnd = ds_display_last_window(seat->display);
     146
     147        if (nwnd != NULL)
     148                ds_seat_set_focus(seat, nwnd);
     149}
     150
    130151/** Post keyboard event to the seat's focused window.
    131152 *
     
    143164        if (event->type == KEY_PRESS && alt_or_shift && event->key == KC_TAB) {
    144165                /* On Alt-Tab or Shift-Tab, switch focus to next window */
    145                 ds_seat_evac_focus(seat, seat->focus);
     166                ds_seat_switch_focus(seat);
    146167                return EOK;
    147168        }
     
    389410
    390411        wnd = ds_display_window_by_pos(seat->display, &seat->pntpos);
    391 
    392         if (seat->focus != wnd) {
     412        if (seat->focus != wnd && seat->focus != NULL) {
    393413                rc = ds_window_post_pos_event(seat->focus, event);
    394414                if (rc != EOK)
  • uspace/srv/hid/display/seat.h

    r08f345f r0da03df  
    5050extern void ds_seat_set_focus(ds_seat_t *, ds_window_t *);
    5151extern void ds_seat_evac_focus(ds_seat_t *, ds_window_t *);
     52extern void ds_seat_switch_focus(ds_seat_t *);
    5253extern errno_t ds_seat_post_kbd_event(ds_seat_t *, kbd_event_t *);
    5354extern errno_t ds_seat_post_ptd_event(ds_seat_t *, ptd_event_t *);
  • uspace/srv/hid/display/test/seat.c

    r08f345f r0da03df  
    9090}
    9191
    92 /** Evacuate focus. */
    93 PCUT_TEST(evac_focus)
     92/** Evacuate focus when another window is available. */
     93PCUT_TEST(evac_focus_two_windows)
    9494{
    9595        ds_display_t *disp;
     
    132132        ds_window_destroy(w0);
    133133        ds_window_destroy(w1);
     134        ds_seat_destroy(seat);
     135        ds_client_destroy(client);
     136        ds_display_destroy(disp);
     137}
     138
     139/** Evacuate focus from the only existing window.
     140 *
     141 * After evacuating no window should be focused
     142 */
     143PCUT_TEST(evac_focus_one_window)
     144{
     145        ds_display_t *disp;
     146        ds_client_t *client;
     147        ds_seat_t *seat;
     148        ds_window_t *wnd;
     149        display_wnd_params_t params;
     150        bool called_cb = false;
     151        errno_t rc;
     152
     153        rc = ds_display_create(NULL, df_none, &disp);
     154        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     155
     156        rc = ds_client_create(disp, &test_ds_client_cb, &called_cb, &client);
     157        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     158
     159        rc = ds_seat_create(disp, &seat);
     160        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     161
     162        display_wnd_params_init(&params);
     163        params.rect.p0.x = params.rect.p0.y = 0;
     164        params.rect.p1.x = params.rect.p1.y = 1;
     165
     166        rc = ds_window_create(client, &params, &wnd);
     167        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     168
     169        ds_seat_set_focus(seat, wnd);
     170        PCUT_ASSERT_EQUALS(wnd, seat->focus);
     171        PCUT_ASSERT_TRUE(called_cb);
     172        called_cb = false;
     173
     174        ds_seat_evac_focus(seat, wnd);
     175        PCUT_ASSERT_NULL(seat->focus);
     176        PCUT_ASSERT_TRUE(called_cb);
     177
     178        ds_window_destroy(wnd);
     179        ds_seat_destroy(seat);
     180        ds_client_destroy(client);
     181        ds_display_destroy(disp);
     182}
     183
     184/** Switch focus when another window is available. */
     185PCUT_TEST(switch_focus_two_windows)
     186{
     187        ds_display_t *disp;
     188        ds_client_t *client;
     189        ds_seat_t *seat;
     190        ds_window_t *w0;
     191        ds_window_t *w1;
     192        display_wnd_params_t params;
     193        bool called_cb = false;
     194        errno_t rc;
     195
     196        rc = ds_display_create(NULL, df_none, &disp);
     197        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     198
     199        rc = ds_client_create(disp, &test_ds_client_cb, &called_cb, &client);
     200        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     201
     202        rc = ds_seat_create(disp, &seat);
     203        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     204
     205        display_wnd_params_init(&params);
     206        params.rect.p0.x = params.rect.p0.y = 0;
     207        params.rect.p1.x = params.rect.p1.y = 1;
     208
     209        rc = ds_window_create(client, &params, &w1);
     210        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     211
     212        rc = ds_window_create(client, &params, &w0);
     213        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     214
     215        ds_seat_set_focus(seat, w1);
     216        PCUT_ASSERT_EQUALS(w1, seat->focus);
     217        PCUT_ASSERT_TRUE(called_cb);
     218        called_cb = false;
     219
     220        ds_seat_switch_focus(seat);
     221        PCUT_ASSERT_EQUALS(w0, seat->focus);
     222        PCUT_ASSERT_TRUE(called_cb);
     223
     224        ds_window_destroy(w0);
     225        ds_window_destroy(w1);
     226        ds_seat_destroy(seat);
     227        ds_client_destroy(client);
     228        ds_display_destroy(disp);
     229}
     230
     231/** Switch focus with just one existing window.
     232 *
     233 * After switching the focus should remain with the same window.
     234 */
     235PCUT_TEST(switch_focus_one_window)
     236{
     237        ds_display_t *disp;
     238        ds_client_t *client;
     239        ds_seat_t *seat;
     240        ds_window_t *wnd;
     241        display_wnd_params_t params;
     242        bool called_cb = false;
     243        errno_t rc;
     244
     245        rc = ds_display_create(NULL, df_none, &disp);
     246        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     247
     248        rc = ds_client_create(disp, &test_ds_client_cb, &called_cb, &client);
     249        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     250
     251        rc = ds_seat_create(disp, &seat);
     252        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     253
     254        display_wnd_params_init(&params);
     255        params.rect.p0.x = params.rect.p0.y = 0;
     256        params.rect.p1.x = params.rect.p1.y = 1;
     257
     258        rc = ds_window_create(client, &params, &wnd);
     259        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     260
     261        ds_seat_set_focus(seat, wnd);
     262        PCUT_ASSERT_EQUALS(wnd, seat->focus);
     263        PCUT_ASSERT_TRUE(called_cb);
     264        called_cb = false;
     265
     266        ds_seat_switch_focus(seat);
     267        PCUT_ASSERT_EQUALS(wnd, seat->focus);
     268        PCUT_ASSERT_FALSE(called_cb);
     269
     270        ds_window_destroy(wnd);
    134271        ds_seat_destroy(seat);
    135272        ds_client_destroy(client);
Note: See TracChangeset for help on using the changeset viewer.