Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/ui/src/window.c

    r3d10a2f rec50d65e  
    11/*
    2  * Copyright (c) 2021 Jiri Svoboda
     2 * Copyright (c) 2024 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    4747#include <stdlib.h>
    4848#include <ui/control.h>
     49#include <ui/menubar.h>
     50#include <ui/menu.h>
     51#include <ui/menuentry.h>
    4952#include <ui/resource.h>
    5053#include <ui/ui.h>
     
    5962
    6063static void dwnd_close_event(void *);
    61 static void dwnd_focus_event(void *);
     64static void dwnd_focus_event(void *, unsigned);
    6265static void dwnd_kbd_event(void *, kbd_event_t *);
    6366static void dwnd_pos_event(void *, pos_event_t *);
    6467static void dwnd_resize_event(void *, gfx_rect_t *);
    65 static void dwnd_unfocus_event(void *);
     68static void dwnd_unfocus_event(void *, unsigned);
    6669
    6770static display_wnd_cb_t dwnd_cb = {
     
    7477};
    7578
     79static void wd_sysmenu_open(ui_wdecor_t *, void *, sysarg_t);
     80static void wd_sysmenu_left(ui_wdecor_t *, void *, sysarg_t);
     81static void wd_sysmenu_right(ui_wdecor_t *, void *, sysarg_t);
     82static void wd_sysmenu_accel(ui_wdecor_t *, void *, char32_t, sysarg_t);
     83static void wd_minimize(ui_wdecor_t *, void *);
     84static void wd_maximize(ui_wdecor_t *, void *);
     85static void wd_unmaximize(ui_wdecor_t *, void *);
    7686static void wd_close(ui_wdecor_t *, void *);
    77 static void wd_move(ui_wdecor_t *, void *, gfx_coord2_t *);
     87static void wd_move(ui_wdecor_t *, void *, gfx_coord2_t *, sysarg_t);
    7888static void wd_resize(ui_wdecor_t *, void *, ui_wdecor_rsztype_t,
    79     gfx_coord2_t *);
     89    gfx_coord2_t *, sysarg_t);
    8090static void wd_set_cursor(ui_wdecor_t *, void *, ui_stock_cursor_t);
    8191
    8292static ui_wdecor_cb_t wdecor_cb = {
     93        .sysmenu_open = wd_sysmenu_open,
     94        .sysmenu_left = wd_sysmenu_left,
     95        .sysmenu_right = wd_sysmenu_right,
     96        .sysmenu_accel = wd_sysmenu_accel,
     97        .minimize = wd_minimize,
     98        .maximize = wd_maximize,
     99        .unmaximize = wd_unmaximize,
    83100        .close = wd_close,
    84101        .move = wd_move,
     
    86103        .set_cursor = wd_set_cursor
    87104};
     105
     106static void wnd_sysmenu_left(ui_menu_t *, void *, sysarg_t);
     107static void wnd_sysmenu_right(ui_menu_t *, void *, sysarg_t);
     108static void wnd_sysmenu_close_req(ui_menu_t *, void *);
     109static void wnd_sysmenu_press_accel(ui_menu_t *, void *, char32_t, sysarg_t);
     110
     111static ui_menu_cb_t wnd_sysmenu_cb = {
     112        .left = wnd_sysmenu_left,
     113        .right = wnd_sysmenu_right,
     114        .close_req = wnd_sysmenu_close_req,
     115        .press_accel = wnd_sysmenu_press_accel
     116};
     117
     118static void wnd_sysmenu_erestore(ui_menu_entry_t *, void *);
     119static void wnd_sysmenu_eminimize(ui_menu_entry_t *, void *);
     120static void wnd_sysmenu_emaximize(ui_menu_entry_t *, void *);
     121static void wnd_sysmenu_eclose(ui_menu_entry_t *, void *);
    88122
    89123static void ui_window_invalidate(void *, gfx_rect_t *);
     
    144178{
    145179        gfx_coord2_t dims;
     180        gfx_coord2_t below_pos;
     181        gfx_rect_t below_rect;
    146182
    147183        assert(params->placement != ui_wnd_place_default ||
     
    177213                break;
    178214        case ui_wnd_place_popup:
    179                 /* Place popup window below parent rectangle */
    180                 pos->x = params->prect.p0.x;
    181                 pos->y = params->prect.p1.y;
     215                /* Compute rectangle when placed below */
     216                below_pos.x = params->prect.p0.x;
     217                below_pos.y = params->prect.p1.y;
     218                gfx_rect_translate(&below_pos, &params->rect, &below_rect);
     219
     220                /* Does below_rect fit within the display? */
     221                if (gfx_rect_is_inside(&below_rect, drect)) {
     222                        /* Place popup window below parent rectangle */
     223                        pos->x = params->prect.p0.x - params->rect.p0.x;
     224                        pos->y = params->prect.p1.y - params->rect.p0.y;
     225                } else {
     226                        /* Place popup window above parent rectangle */
     227                        pos->x = params->prect.p0.x;
     228                        pos->y = params->prect.p0.y -
     229                            (params->rect.p1.y - params->rect.p0.y);
     230                }
    182231                break;
    183232        }
     233}
     234
     235/** Create window's system menu.
     236 *
     237 * @param window Window
     238 * @return EOK on success or an error code
     239 */
     240static errno_t ui_window_sysmenu_create(ui_window_t *window)
     241{
     242        errno_t rc;
     243        ui_menu_entry_t *mrestore;
     244        ui_menu_entry_t *mmin;
     245        ui_menu_entry_t *mmax;
     246        ui_menu_entry_t *msep;
     247        ui_menu_entry_t *mclose;
     248
     249        rc = ui_menu_create(window, &window->sysmenu);
     250        if (rc != EOK)
     251                goto error;
     252
     253        ui_menu_set_cb(window->sysmenu, &wnd_sysmenu_cb, (void *)window);
     254
     255        rc = ui_menu_entry_create(window->sysmenu, "~R~estore",
     256            "", &mrestore);
     257        if (rc != EOK)
     258                goto error;
     259
     260        if (!window->wdecor->maximized)
     261                ui_menu_entry_set_disabled(mrestore, true);
     262
     263        ui_menu_entry_set_cb(mrestore, wnd_sysmenu_erestore, (void *)window);
     264
     265        rc = ui_menu_entry_create(window->sysmenu, "Mi~n~imize",
     266            "", &mmin);
     267        if (rc != EOK)
     268                goto error;
     269
     270        if ((window->wdecor->style & ui_wds_minimize_btn) == 0)
     271                ui_menu_entry_set_disabled(mmin, true);
     272
     273        ui_menu_entry_set_cb(mmin, wnd_sysmenu_eminimize, (void *)window);
     274
     275        rc = ui_menu_entry_create(window->sysmenu, "Ma~x~imize",
     276            "", &mmax);
     277        if (rc != EOK)
     278                goto error;
     279
     280        if ((window->wdecor->style & ui_wds_maximize_btn) == 0 ||
     281            window->wdecor->maximized)
     282                ui_menu_entry_set_disabled(mmax, true);
     283
     284        ui_menu_entry_set_cb(mmax, wnd_sysmenu_emaximize, (void *)window);
     285
     286        rc = ui_menu_entry_sep_create(window->sysmenu, &msep);
     287        if (rc != EOK)
     288                goto error;
     289
     290        rc = ui_menu_entry_create(window->sysmenu, "~C~lose", "Alt-F4",
     291            &mclose);
     292        if (rc != EOK)
     293                goto error;
     294
     295        if ((window->wdecor->style & ui_wds_close_btn) == 0)
     296                ui_menu_entry_set_disabled(mclose, true);
     297
     298        ui_menu_entry_set_cb(mclose, wnd_sysmenu_eclose, (void *)window);
     299
     300        window->sysmenu_restore = mrestore;
     301        window->sysmenu_minimize = mmin;
     302        window->sysmenu_maximize = mmax;
     303
     304        return EOK;
     305error:
     306        return rc;
    184307}
    185308
     
    195318{
    196319        ui_window_t *window;
     320        ui_window_t *pwindow = NULL;
    197321        display_info_t info;
    198322        gfx_coord2_t scr_dims;
     
    218342        display_wnd_params_init(&dparams);
    219343        dparams.rect = params->rect;
     344        dparams.caption = params->caption;
    220345        /* Only allow making the window larger */
    221346        gfx_rect_dims(&params->rect, &dparams.min_size);
    222347
     348        /*
     349         * If idev_id is not specified, use the UI default (probably
     350         * obtained from display specification. This creates the
     351         * main window in the seat specified on the command line.
     352         */
     353        if (params->idev_id != 0)
     354                dparams.idev_id = params->idev_id;
     355        else
     356                dparams.idev_id = ui->idev_id;
     357
    223358        if ((params->flags & ui_wndf_popup) != 0)
    224359                dparams.flags |= wndf_popup;
     360        if ((params->flags & ui_wndf_topmost) != 0)
     361                dparams.flags |= wndf_topmost;
     362        if ((params->flags & ui_wndf_system) != 0)
     363                dparams.flags |= wndf_system;
     364        if ((params->flags & ui_wndf_avoid) != 0)
     365                dparams.flags |= wndf_avoid;
    225366
    226367        if (ui->display != NULL) {
     
    262403                        gfx_coord2_add(&dparams.rect.p0, &scr_dims,
    263404                            &dparams.rect.p1);
     405                        (void) console_set_caption(ui->console,
     406                            params->caption);
    264407                }
    265408        } else {
     
    355498        window->wdecor = wdecor;
    356499        window->cursor = ui_curs_arrow;
     500        window->placement = params->placement;
     501
     502        rc = ui_window_sysmenu_create(window);
     503        if (rc != EOK)
     504                goto error;
     505
    357506        *rwindow = window;
    358507
     508        if (ui_is_fullscreen(ui))
     509                pwindow = ui_window_get_active(ui);
     510
    359511        list_append(&window->lwindows, &ui->windows);
     512
     513        if (ui_is_fullscreen(ui)) {
     514                /* Send unfocus event to previously active window */
     515                if (pwindow != NULL)
     516                        ui_window_send_unfocus(pwindow, 0);
     517        }
     518
    360519        return EOK;
    361520error:
     
    383542{
    384543        ui_t *ui;
     544        ui_window_t *nwindow;
    385545
    386546        if (window == NULL)
     
    391551        list_remove(&window->lwindows);
    392552        ui_control_destroy(window->control);
     553        ui_menu_destroy(window->sysmenu);
    393554        ui_wdecor_destroy(window->wdecor);
    394555        ui_resource_destroy(window->res);
    395         if (0 && window->app_mgc != NULL)
     556        if (window->app_mgc != NULL)
    396557                mem_gc_delete(window->app_mgc);
    397         if (0 && window->app_bmp != NULL)
     558        if (window->app_bmp != NULL)
    398559                gfx_bitmap_destroy(window->app_bmp);
    399560        if (window->mgc != NULL) {
     
    406567                display_window_destroy(window->dwindow);
    407568
    408         free(window);
    409 
    410569        /* Need to repaint if windows are emulated */
    411570        if (ui_is_fullscreen(ui)) {
    412571                ui_paint(ui);
    413         }
     572                /* Send focus event to newly active window */
     573                nwindow = ui_window_get_active(ui);
     574                if (nwindow != NULL)
     575                        ui_window_send_focus(nwindow, 0);
     576        }
     577
     578        if (ui->console != NULL &&
     579            window->placement == ui_wnd_place_full_screen) {
     580                (void) console_set_caption(ui->console, "");
     581        }
     582
     583        free(window);
    414584}
    415585
     
    421591 * @param window Window
    422592 * @param control Control
    423  * @return EOK on success, ENOMEM if out of memory
    424593 */
    425594void ui_window_add(ui_window_t *window, ui_control_t *control)
     
    461630}
    462631
    463 /** Resize/move window.
    464  *
    465  * Resize window to the dimensions of @a rect. If @a rect.p0 is not 0,0,
    466  * the top-left corner of the window will move on the screen accordingly.
     632/** Resize or (un)maximize window.
    467633 *
    468634 * @param window Window
    469635 * @param rect Rectangle
     636 * @param scop Size change operation
    470637 *
    471638 * @return EOK on success or an error code
    472639 */
    473 errno_t ui_window_resize(ui_window_t *window, gfx_rect_t *rect)
     640errno_t ui_window_size_change(ui_window_t *window, gfx_rect_t *rect,
     641    ui_wnd_sc_op_t scop)
    474642{
    475643        gfx_coord2_t offs;
     
    537705        }
    538706
    539         /* dwindow can be NULL in case of unit tests */
     707        /* dwindow can be NULL in case of unit tests or fullscreen mode */
    540708        if (window->dwindow != NULL) {
    541                 rc = display_window_resize(window->dwindow, &offs, &nrect);
    542                 if (rc != EOK)
    543                         goto error;
     709                switch (scop) {
     710                case ui_wsc_resize:
     711                        rc = display_window_resize(window->dwindow, &offs,
     712                            &nrect);
     713                        if (rc != EOK)
     714                                goto error;
     715                        break;
     716                case ui_wsc_maximize:
     717                        rc = display_window_maximize(window->dwindow);
     718                        if (rc != EOK)
     719                                goto error;
     720                        break;
     721                case ui_wsc_unmaximize:
     722                        rc = display_window_unmaximize(window->dwindow);
     723                        if (rc != EOK)
     724                                goto error;
     725                        break;
     726                }
    544727        }
    545728
     
    561744                        goto error;
    562745#endif
    563 
    564746                mem_gc_retarget(window->mgc, &win_params.rect, &win_alloc);
    565747
     
    568750        }
    569751
     752        window->rect = nrect;
    570753        ui_wdecor_set_rect(window->wdecor, &nrect);
    571754        ui_wdecor_paint(window->wdecor);
     
    589772}
    590773
     774/** Resize/move window.
     775 *
     776 * Resize window to the dimensions of @a rect. If @a rect.p0 is not 0,0,
     777 * the top-left corner of the window will move on the screen accordingly.
     778 *
     779 * @param window Window
     780 * @param rect Rectangle
     781 *
     782 * @return EOK on success or an error code
     783 */
     784errno_t ui_window_resize(ui_window_t *window, gfx_rect_t *rect)
     785{
     786        return ui_window_size_change(window, rect, ui_wsc_resize);
     787}
     788
    591789/** Set window callbacks.
    592790 *
     
    599797        window->cb = cb;
    600798        window->arg = arg;
     799}
     800
     801/** Change window caption.
     802 *
     803 * @param window Window
     804 * @param caption New caption
     805 *
     806 * @return EOK on success or an error code
     807 */
     808errno_t ui_window_set_caption(ui_window_t *window, const char *caption)
     809{
     810        errno_t rc;
     811
     812        /* Set console caption if fullscreen window on console */
     813        if (window->ui->console != NULL && window->placement ==
     814            ui_wnd_place_full_screen) {
     815                rc = console_set_caption(window->ui->console, caption);
     816                if (rc != EOK)
     817                        return rc;
     818        }
     819
     820        /* Set display window caption if running on display service */
     821        if (window->dwindow != NULL) {
     822                rc = display_window_set_caption(window->dwindow, caption);
     823                if (rc != EOK)
     824                        return rc;
     825        }
     826
     827        return ui_wdecor_set_caption(window->wdecor, caption);
    601828}
    602829
     
    746973{
    747974        ui_window_t *window = (ui_window_t *) arg;
    748 
     975        ui_t *ui = window->ui;
     976
     977        ui_lock(ui);
    749978        ui_window_send_close(window);
     979        ui_unlock(ui);
    750980}
    751981
    752982/** Handle window focus event. */
    753 static void dwnd_focus_event(void *arg)
    754 {
    755         ui_window_t *window = (ui_window_t *) arg;
     983static void dwnd_focus_event(void *arg, unsigned nfocus)
     984{
     985        ui_window_t *window = (ui_window_t *) arg;
     986        ui_t *ui = window->ui;
     987
     988        ui_lock(ui);
     989        (void)nfocus;
    756990
    757991        if (window->wdecor != NULL) {
     
    760994        }
    761995
    762         ui_window_send_focus(window);
     996        ui_window_send_focus(window, nfocus);
     997        ui_unlock(ui);
    763998}
    764999
     
    7671002{
    7681003        ui_window_t *window = (ui_window_t *) arg;
    769 
    770         (void) window;
     1004        ui_t *ui = window->ui;
     1005
     1006        ui_lock(ui);
    7711007        ui_window_send_kbd(window, kbd_event);
     1008        ui_unlock(ui);
    7721009}
    7731010
     
    7761013{
    7771014        ui_window_t *window = (ui_window_t *) arg;
     1015        ui_t *ui = window->ui;
     1016        ui_evclaim_t claim;
    7781017
    7791018        /* Make sure we don't process events until fully initialized */
     
    7811020                return;
    7821021
    783         ui_wdecor_pos_event(window->wdecor, event);
     1022        ui_lock(ui);
     1023
     1024        claim = ui_wdecor_pos_event(window->wdecor, event);
     1025        if (claim == ui_claimed) {
     1026                ui_unlock(ui);
     1027                return;
     1028        }
     1029
    7841030        ui_window_send_pos(window, event);
     1031        ui_unlock(ui);
    7851032}
    7861033
     
    7891036{
    7901037        ui_window_t *window = (ui_window_t *) arg;
     1038        ui_t *ui = window->ui;
    7911039
    7921040        /* Make sure we don't process events until fully initialized */
     
    7971045                return;
    7981046
     1047        ui_lock(ui);
    7991048        (void) ui_window_resize(window, rect);
    8001049        (void) ui_window_paint(window);
     1050        ui_unlock(ui);
    8011051}
    8021052
    8031053/** Handle window unfocus event. */
    804 static void dwnd_unfocus_event(void *arg)
    805 {
    806         ui_window_t *window = (ui_window_t *) arg;
    807 
    808         if (window->wdecor != NULL) {
     1054static void dwnd_unfocus_event(void *arg, unsigned nfocus)
     1055{
     1056        ui_window_t *window = (ui_window_t *) arg;
     1057        ui_t *ui = window->ui;
     1058
     1059        ui_lock(ui);
     1060
     1061        if (window->wdecor != NULL && nfocus == 0) {
    8091062                ui_wdecor_set_active(window->wdecor, false);
    8101063                ui_wdecor_paint(window->wdecor);
    8111064        }
    8121065
    813         ui_window_send_unfocus(window);
     1066        ui_window_send_unfocus(window, nfocus);
     1067        ui_unlock(ui);
     1068}
     1069
     1070/** Window decoration requested opening of system menu.
     1071 *
     1072 * @param wdecor Window decoration
     1073 * @param arg Argument (window)
     1074 * @param idev_id Input device ID
     1075 */
     1076static void wd_sysmenu_open(ui_wdecor_t *wdecor, void *arg, sysarg_t idev_id)
     1077{
     1078        ui_window_t *window = (ui_window_t *) arg;
     1079
     1080        ui_window_send_sysmenu(window, idev_id);
     1081}
     1082
     1083/** Window decoration requested moving left from system menu handle.
     1084 *
     1085 * @param wdecor Window decoration
     1086 * @param arg Argument (window)
     1087 * @param idev_id Input device ID
     1088 */
     1089static void wd_sysmenu_left(ui_wdecor_t *wdecor, void *arg, sysarg_t idev_id)
     1090{
     1091        ui_window_t *window = (ui_window_t *) arg;
     1092
     1093        if (window->mbar != NULL) {
     1094                ui_wdecor_sysmenu_hdl_set_active(window->wdecor, false);
     1095                ui_menu_close(window->sysmenu);
     1096                ui_menu_bar_select_last(window->mbar, false, idev_id);
     1097        }
     1098}
     1099
     1100/** Window decoration requested moving right from system menu handle.
     1101 *
     1102 * @param wdecor Window decoration
     1103 * @param arg Argument (window)
     1104 * @param idev_id Input device ID
     1105 */
     1106static void wd_sysmenu_right(ui_wdecor_t *wdecor, void *arg, sysarg_t idev_id)
     1107{
     1108        ui_window_t *window = (ui_window_t *) arg;
     1109
     1110        if (window->mbar != NULL) {
     1111                ui_wdecor_sysmenu_hdl_set_active(window->wdecor, false);
     1112                ui_menu_close(window->sysmenu);
     1113                ui_menu_bar_select_first(window->mbar, false, idev_id);
     1114        }
     1115}
     1116
     1117/** Window decoration detected accelerator press from system menu handle.
     1118 *
     1119 * @param wdecor Window decoration
     1120 * @param arg Argument (window)
     1121 * @param c Accelerator key
     1122 * @param idev_id Input device ID
     1123 */
     1124static void wd_sysmenu_accel(ui_wdecor_t *wdecor, void *arg, char32_t c,
     1125    sysarg_t idev_id)
     1126{
     1127        ui_window_t *window = (ui_window_t *) arg;
     1128
     1129        if (window->mbar != NULL) {
     1130                ui_wdecor_sysmenu_hdl_set_active(window->wdecor, false);
     1131                ui_menu_close(window->sysmenu);
     1132                ui_menu_bar_press_accel(window->mbar, c, idev_id);
     1133        }
     1134}
     1135
     1136/** Window decoration requested window minimization.
     1137 *
     1138 * @param wdecor Window decoration
     1139 * @param arg Argument (window)
     1140 */
     1141static void wd_minimize(ui_wdecor_t *wdecor, void *arg)
     1142{
     1143        ui_window_t *window = (ui_window_t *) arg;
     1144
     1145        ui_window_send_minimize(window);
     1146}
     1147
     1148/** Window decoration requested window maximization.
     1149 *
     1150 * @param wdecor Window decoration
     1151 * @param arg Argument (window)
     1152 */
     1153static void wd_maximize(ui_wdecor_t *wdecor, void *arg)
     1154{
     1155        ui_window_t *window = (ui_window_t *) arg;
     1156
     1157        ui_window_send_maximize(window);
     1158}
     1159
     1160/** Window decoration requested window unmaximization.
     1161 *
     1162 * @param wdecor Window decoration
     1163 * @param arg Argument (window)
     1164 */
     1165static void wd_unmaximize(ui_wdecor_t *wdecor, void *arg)
     1166{
     1167        ui_window_t *window = (ui_window_t *) arg;
     1168
     1169        ui_window_send_unmaximize(window);
    8141170}
    8151171
     
    8311187 * @param arg Argument (window)
    8321188 * @param pos Position where the title bar was pressed
    833  */
    834 static void wd_move(ui_wdecor_t *wdecor, void *arg, gfx_coord2_t *pos)
     1189 * @param pos_id Positioning device ID
     1190 */
     1191static void wd_move(ui_wdecor_t *wdecor, void *arg, gfx_coord2_t *pos,
     1192    sysarg_t pos_id)
    8351193{
    8361194        ui_window_t *window = (ui_window_t *) arg;
    8371195
    8381196        if (window->dwindow != NULL)
    839                 (void) display_window_move_req(window->dwindow, pos);
     1197                (void) display_window_move_req(window->dwindow, pos, pos_id);
    8401198}
    8411199
     
    8461204 * @param rsztype Resize type
    8471205 * @param pos Position where the button was pressed
     1206 * @param pos_id Positioning device ID
    8481207 */
    8491208static void wd_resize(ui_wdecor_t *wdecor, void *arg,
    850     ui_wdecor_rsztype_t rsztype, gfx_coord2_t *pos)
    851 {
    852         ui_window_t *window = (ui_window_t *) arg;
    853 
    854         if (window->dwindow != NULL)
    855                 (void) display_window_resize_req(window->dwindow, rsztype, pos);
     1209    ui_wdecor_rsztype_t rsztype, gfx_coord2_t *pos, sysarg_t pos_id)
     1210{
     1211        ui_window_t *window = (ui_window_t *) arg;
     1212
     1213        if (window->dwindow != NULL) {
     1214                (void) display_window_resize_req(window->dwindow,
     1215                    (display_wnd_rsztype_t) rsztype, // Same constants in the enums
     1216                    pos, pos_id);
     1217        }
    8561218}
    8571219
     
    9141276}
    9151277
     1278/** Send window sysmenu event.
     1279 *
     1280 * @param window Window
     1281 * @parma idev_id Input device ID
     1282 */
     1283void ui_window_send_sysmenu(ui_window_t *window, sysarg_t idev_id)
     1284{
     1285        if (window->cb != NULL && window->cb->sysmenu != NULL)
     1286                window->cb->sysmenu(window, window->arg, idev_id);
     1287        else
     1288                ui_window_def_sysmenu(window, idev_id);
     1289}
     1290
     1291/** Send window minimize event.
     1292 *
     1293 * @param window Window
     1294 */
     1295void ui_window_send_minimize(ui_window_t *window)
     1296{
     1297        if (window->cb != NULL && window->cb->maximize != NULL)
     1298                window->cb->minimize(window, window->arg);
     1299        else
     1300                ui_window_def_minimize(window);
     1301}
     1302
     1303/** Send window maximize event.
     1304 *
     1305 * @param window Window
     1306 */
     1307void ui_window_send_maximize(ui_window_t *window)
     1308{
     1309        if (window->cb != NULL && window->cb->maximize != NULL)
     1310                window->cb->maximize(window, window->arg);
     1311        else
     1312                ui_window_def_maximize(window);
     1313}
     1314
     1315/** Send window unmaximize event.
     1316 *
     1317 * @param window Window
     1318 */
     1319void ui_window_send_unmaximize(ui_window_t *window)
     1320{
     1321        if (window->cb != NULL && window->cb->unmaximize != NULL)
     1322                window->cb->unmaximize(window, window->arg);
     1323        else
     1324                ui_window_def_unmaximize(window);
     1325}
     1326
    9161327/** Send window close event.
    9171328 *
     
    9271338 *
    9281339 * @param window Window
    929  */
    930 void ui_window_send_focus(ui_window_t *window)
     1340 * @param nfocus New number of foci
     1341 */
     1342void ui_window_send_focus(ui_window_t *window, unsigned nfocus)
    9311343{
    9321344        if (window->cb != NULL && window->cb->focus != NULL)
    933                 window->cb->focus(window, window->arg);
     1345                window->cb->focus(window, window->arg, nfocus);
    9341346}
    9351347
     
    9431355                window->cb->kbd(window, window->arg, kbd);
    9441356        else
    945                 return ui_window_def_kbd(window, kbd);
     1357                ui_window_def_kbd(window, kbd);
    9461358}
    9471359
     
    9731385 *
    9741386 * @param window Window
    975  */
    976 void ui_window_send_unfocus(ui_window_t *window)
     1387 * @param nfocus Number of remaining foci
     1388 */
     1389void ui_window_send_unfocus(ui_window_t *window, unsigned nfocus)
    9771390{
    9781391        if (window->cb != NULL && window->cb->unfocus != NULL)
    979                 window->cb->unfocus(window, window->arg);
     1392                window->cb->unfocus(window, window->arg, nfocus);
    9801393        else
    981                 return ui_window_def_unfocus(window);
     1394                return ui_window_def_unfocus(window, nfocus);
     1395}
     1396
     1397/** Default window sysmenu routine.
     1398 *
     1399 * @param window Window
     1400 * @param idev_id Input device ID
     1401 * @return EOK on success or an error code
     1402 */
     1403errno_t ui_window_def_sysmenu(ui_window_t *window, sysarg_t idev_id)
     1404{
     1405        errno_t rc;
     1406        ui_wdecor_geom_t geom;
     1407
     1408        if (ui_menu_is_open(window->sysmenu)) {
     1409                ui_menu_close(window->sysmenu);
     1410        } else {
     1411                ui_wdecor_get_geom(window->wdecor, &geom);
     1412
     1413                rc = ui_menu_open(window->sysmenu, &geom.title_bar_rect,
     1414                    idev_id);
     1415                if (rc != EOK)
     1416                        goto error;
     1417        }
     1418
     1419        return EOK;
     1420error:
     1421        return rc;
     1422}
     1423
     1424/** Default window minimize routine.
     1425 *
     1426 * @param window Window
     1427 * @return EOK on success or an error code
     1428 */
     1429errno_t ui_window_def_minimize(ui_window_t *window)
     1430{
     1431        errno_t rc;
     1432
     1433        if (window->dwindow != NULL) {
     1434                rc = display_window_minimize(window->dwindow);
     1435                if (rc != EOK)
     1436                        goto error;
     1437        }
     1438
     1439        return EOK;
     1440error:
     1441        return rc;
     1442}
     1443
     1444/** Default window maximize routine.
     1445 *
     1446 * @param window Window
     1447 * @return EOK on success or an error code
     1448 */
     1449errno_t ui_window_def_maximize(ui_window_t *window)
     1450{
     1451        errno_t rc;
     1452        gfx_rect_t old_rect;
     1453        gfx_rect_t rect;
     1454
     1455        old_rect = window->rect;
     1456
     1457        if (window->dwindow != NULL) {
     1458                rc = display_window_get_max_rect(window->dwindow, &rect);
     1459                if (rc != EOK)
     1460                        return rc;
     1461        } else {
     1462                rect = window->ui->rect;
     1463        }
     1464
     1465        ui_wdecor_set_maximized(window->wdecor, true);
     1466        ui_menu_entry_set_disabled(window->sysmenu_restore, false);
     1467        ui_menu_entry_set_disabled(window->sysmenu_maximize, true);
     1468
     1469        rc = ui_window_size_change(window, &rect, ui_wsc_maximize);
     1470        if (rc != EOK) {
     1471                ui_wdecor_set_maximized(window->wdecor, false);
     1472                return rc;
     1473        }
     1474
     1475        window->normal_rect = old_rect;
     1476        (void) ui_window_paint(window);
     1477        return EOK;
     1478}
     1479
     1480/** Default window unmaximize routine.
     1481 *
     1482 * @param window Window
     1483 * @return EOK on success or an error code
     1484 */
     1485errno_t ui_window_def_unmaximize(ui_window_t *window)
     1486{
     1487        errno_t rc;
     1488
     1489        ui_wdecor_set_maximized(window->wdecor, false);
     1490        ui_menu_entry_set_disabled(window->sysmenu_restore, true);
     1491        ui_menu_entry_set_disabled(window->sysmenu_maximize, false);
     1492
     1493        rc = ui_window_size_change(window, &window->normal_rect,
     1494            ui_wsc_unmaximize);
     1495        if (rc != EOK) {
     1496                ui_wdecor_set_maximized(window->wdecor, true);
     1497                printf("ui_window_size_change->error\n");
     1498                return rc;
     1499        }
     1500
     1501        (void) ui_window_paint(window);
     1502        return EOK;
    9821503}
    9831504
     
    9851506 *
    9861507 * @param window Window
    987  */
    988 void ui_window_def_kbd(ui_window_t *window, kbd_event_t *kbd)
    989 {
     1508 * @return ui_claimed iff event was claimed
     1509 */
     1510ui_evclaim_t ui_window_def_kbd(ui_window_t *window, kbd_event_t *kbd)
     1511{
     1512        ui_evclaim_t claim;
     1513
    9901514        if (window->control != NULL)
    991                 ui_control_kbd_event(window->control, kbd);
     1515                claim = ui_control_kbd_event(window->control, kbd);
     1516        else
     1517                claim = ui_unclaimed;
     1518
     1519        if (claim == ui_unclaimed)
     1520                return ui_wdecor_kbd_event(window->wdecor, kbd);
     1521
     1522        return ui_unclaimed;
    9921523}
    9931524
     
    10351566 *
    10361567 * @param window Window
     1568 * @param nfocus Number of remaining foci
    10371569 * @return EOK on success or an error code
    10381570 */
    1039 void ui_window_def_unfocus(ui_window_t *window)
     1571void ui_window_def_unfocus(ui_window_t *window, unsigned nfocus)
    10401572{
    10411573        if (window->control != NULL)
    1042                 ui_control_unfocus(window->control);
     1574                ui_control_unfocus(window->control, nfocus);
     1575}
     1576
     1577/** Handle system menu left event.
     1578 *
     1579 * @param sysmenu System menu
     1580 * @param arg Argument (ui_window_t *)
     1581 * @param idev_id Input device ID
     1582 */
     1583static void wnd_sysmenu_left(ui_menu_t *sysmenu, void *arg, sysarg_t idev_id)
     1584{
     1585        ui_window_t *window = (ui_window_t *)arg;
     1586
     1587        if (window->mbar != NULL) {
     1588                ui_wdecor_sysmenu_hdl_set_active(window->wdecor, false);
     1589                ui_menu_close(sysmenu);
     1590                ui_menu_bar_select_last(window->mbar, true, idev_id);
     1591        }
     1592}
     1593
     1594/** Handle system menu right event.
     1595 *
     1596 * @param sysmenu System menu
     1597 * @param arg Argument (ui_window_t *)
     1598 * @param idev_id Input device ID
     1599 */
     1600static void wnd_sysmenu_right(ui_menu_t *sysmenu, void *arg, sysarg_t idev_id)
     1601{
     1602        ui_window_t *window = (ui_window_t *)arg;
     1603
     1604        if (window->mbar != NULL) {
     1605                ui_wdecor_sysmenu_hdl_set_active(window->wdecor, false);
     1606                ui_menu_close(sysmenu);
     1607                ui_menu_bar_select_first(window->mbar, true, idev_id);
     1608        }
     1609}
     1610
     1611/** Handle system menu close request event.
     1612 *
     1613 * @param sysmenu System menu
     1614 * @param arg Argument (ui_window_t *)
     1615 * @param idev_id Input device ID
     1616 */
     1617static void wnd_sysmenu_close_req(ui_menu_t *sysmenu, void *arg)
     1618{
     1619        ui_window_t *window = (ui_window_t *)arg;
     1620
     1621        ui_wdecor_sysmenu_hdl_set_active(window->wdecor, false);
     1622        ui_menu_close(sysmenu);
     1623}
     1624
     1625/** Handle system menu Restore entry activation.
     1626 *
     1627 * @param mentry Menu entry
     1628 * @param arg Argument (ui_window_t *)
     1629 */
     1630static void wnd_sysmenu_erestore(ui_menu_entry_t *mentry, void *arg)
     1631{
     1632        ui_window_t *window = (ui_window_t *)arg;
     1633
     1634        ui_window_send_unmaximize(window);
     1635}
     1636
     1637/** Handle system menu Minimize entry activation.
     1638 *
     1639 * @param mentry Menu entry
     1640 * @param arg Argument (ui_window_t *)
     1641 */
     1642static void wnd_sysmenu_eminimize(ui_menu_entry_t *mentry, void *arg)
     1643{
     1644        ui_window_t *window = (ui_window_t *)arg;
     1645
     1646        ui_window_send_minimize(window);
     1647}
     1648
     1649/** Handle system menu Maximize entry activation.
     1650 *
     1651 * @param mentry Menu entry
     1652 * @param arg Argument (ui_window_t *)
     1653 */
     1654static void wnd_sysmenu_emaximize(ui_menu_entry_t *mentry, void *arg)
     1655{
     1656        ui_window_t *window = (ui_window_t *)arg;
     1657
     1658        ui_window_send_maximize(window);
     1659}
     1660
     1661/** Handle system menu Close entry activation.
     1662 *
     1663 * @param mentry Menu entry
     1664 * @param arg Argument (ui_window_t *)
     1665 */
     1666static void wnd_sysmenu_eclose(ui_menu_entry_t *mentry, void *arg)
     1667{
     1668        ui_window_t *window = (ui_window_t *)arg;
     1669
     1670        ui_window_send_close(window);
     1671}
     1672
     1673/** Handle system menu press accelerator key event.
     1674 *
     1675 * @param sysmenu System menu
     1676 * @param arg Argument (ui_window_t *)
     1677 * @param idev_id Input device ID
     1678 */
     1679static void wnd_sysmenu_press_accel(ui_menu_t *sysmenu, void *arg,
     1680    char32_t c, sysarg_t idev_id)
     1681{
     1682        (void)sysmenu;
     1683        (void)arg;
     1684        (void)c;
     1685        (void)idev_id;
    10431686}
    10441687
Note: See TracChangeset for help on using the changeset viewer.