Ignore:
File:
1 edited

Legend:

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

    r3d10a2f r0d00e53  
    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 ||
     
    153189        switch (params->placement) {
    154190        case ui_wnd_place_default:
    155                 assert(ui_is_fullscreen(window->ui));
     191        case ui_wnd_place_center:
     192                assert(params->placement != ui_wnd_place_default ||
     193                    ui_is_fullscreen(window->ui));
    156194                /* Center window */
    157195                gfx_rect_dims(&params->rect, &dims);
     
    177215                break;
    178216        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;
     217                /* Compute rectangle when placed below */
     218                below_pos.x = params->prect.p0.x;
     219                below_pos.y = params->prect.p1.y;
     220                gfx_rect_translate(&below_pos, &params->rect, &below_rect);
     221
     222                /* Does below_rect fit within the display? */
     223                if (gfx_rect_is_inside(&below_rect, drect)) {
     224                        /* Place popup window below parent rectangle */
     225                        pos->x = params->prect.p0.x - params->rect.p0.x;
     226                        pos->y = params->prect.p1.y - params->rect.p0.y;
     227                } else {
     228                        /* Place popup window above parent rectangle */
     229                        pos->x = params->prect.p0.x;
     230                        pos->y = params->prect.p0.y -
     231                            (params->rect.p1.y - params->rect.p0.y);
     232                }
    182233                break;
    183234        }
     235}
     236
     237/** Create window's system menu.
     238 *
     239 * @param window Window
     240 * @return EOK on success or an error code
     241 */
     242static errno_t ui_window_sysmenu_create(ui_window_t *window)
     243{
     244        errno_t rc;
     245        ui_menu_entry_t *mrestore;
     246        ui_menu_entry_t *mmin;
     247        ui_menu_entry_t *mmax;
     248        ui_menu_entry_t *msep;
     249        ui_menu_entry_t *mclose;
     250
     251        rc = ui_menu_create(window, &window->sysmenu);
     252        if (rc != EOK)
     253                goto error;
     254
     255        ui_menu_set_cb(window->sysmenu, &wnd_sysmenu_cb, (void *)window);
     256
     257        rc = ui_menu_entry_create(window->sysmenu, "~R~estore",
     258            "", &mrestore);
     259        if (rc != EOK)
     260                goto error;
     261
     262        if (!window->wdecor->maximized)
     263                ui_menu_entry_set_disabled(mrestore, true);
     264
     265        ui_menu_entry_set_cb(mrestore, wnd_sysmenu_erestore, (void *)window);
     266
     267        rc = ui_menu_entry_create(window->sysmenu, "Mi~n~imize",
     268            "", &mmin);
     269        if (rc != EOK)
     270                goto error;
     271
     272        if ((window->wdecor->style & ui_wds_minimize_btn) == 0)
     273                ui_menu_entry_set_disabled(mmin, true);
     274
     275        ui_menu_entry_set_cb(mmin, wnd_sysmenu_eminimize, (void *)window);
     276
     277        rc = ui_menu_entry_create(window->sysmenu, "Ma~x~imize",
     278            "", &mmax);
     279        if (rc != EOK)
     280                goto error;
     281
     282        if ((window->wdecor->style & ui_wds_maximize_btn) == 0 ||
     283            window->wdecor->maximized)
     284                ui_menu_entry_set_disabled(mmax, true);
     285
     286        ui_menu_entry_set_cb(mmax, wnd_sysmenu_emaximize, (void *)window);
     287
     288        rc = ui_menu_entry_sep_create(window->sysmenu, &msep);
     289        if (rc != EOK)
     290                goto error;
     291
     292        rc = ui_menu_entry_create(window->sysmenu, "~C~lose", "Alt-F4",
     293            &mclose);
     294        if (rc != EOK)
     295                goto error;
     296
     297        if ((window->wdecor->style & ui_wds_close_btn) == 0)
     298                ui_menu_entry_set_disabled(mclose, true);
     299
     300        ui_menu_entry_set_cb(mclose, wnd_sysmenu_eclose, (void *)window);
     301
     302        window->sysmenu_restore = mrestore;
     303        window->sysmenu_minimize = mmin;
     304        window->sysmenu_maximize = mmax;
     305
     306        return EOK;
     307error:
     308        return rc;
    184309}
    185310
     
    195320{
    196321        ui_window_t *window;
     322        ui_window_t *pwindow = NULL;
    197323        display_info_t info;
    198324        gfx_coord2_t scr_dims;
     
    218344        display_wnd_params_init(&dparams);
    219345        dparams.rect = params->rect;
    220         /* Only allow making the window larger */
    221         gfx_rect_dims(&params->rect, &dparams.min_size);
     346        dparams.caption = params->caption;
     347        dparams.min_size = params->min_size;
     348
     349        /*
     350         * If idev_id is not specified, use the UI default (probably
     351         * obtained from display specification. This creates the
     352         * main window in the seat specified on the command line.
     353         */
     354        if (params->idev_id != 0)
     355                dparams.idev_id = params->idev_id;
     356        else
     357                dparams.idev_id = ui->idev_id;
    222358
    223359        if ((params->flags & ui_wndf_popup) != 0)
    224360                dparams.flags |= wndf_popup;
     361        if ((params->flags & ui_wndf_nofocus) != 0)
     362                dparams.flags |= wndf_nofocus;
     363        if ((params->flags & ui_wndf_topmost) != 0)
     364                dparams.flags |= wndf_topmost;
     365        if ((params->flags & ui_wndf_system) != 0)
     366                dparams.flags |= wndf_system;
     367        if ((params->flags & ui_wndf_avoid) != 0)
     368                dparams.flags |= wndf_avoid;
    225369
    226370        if (ui->display != NULL) {
     
    262406                        gfx_coord2_add(&dparams.rect.p0, &scr_dims,
    263407                            &dparams.rect.p1);
     408                        (void) console_set_caption(ui->console,
     409                            params->caption);
    264410                }
    265411        } else {
     
    355501        window->wdecor = wdecor;
    356502        window->cursor = ui_curs_arrow;
     503        window->placement = params->placement;
     504
     505        rc = ui_window_sysmenu_create(window);
     506        if (rc != EOK)
     507                goto error;
     508
    357509        *rwindow = window;
    358510
     511        if (ui_is_fullscreen(ui))
     512                pwindow = ui_window_get_active(ui);
     513
    359514        list_append(&window->lwindows, &ui->windows);
     515
     516        if (ui_is_fullscreen(ui)) {
     517                /* Send unfocus event to previously active window */
     518                if (pwindow != NULL)
     519                        ui_window_send_unfocus(pwindow, 0);
     520        }
     521
    360522        return EOK;
    361523error:
     
    383545{
    384546        ui_t *ui;
     547        ui_window_t *nwindow;
    385548
    386549        if (window == NULL)
     
    391554        list_remove(&window->lwindows);
    392555        ui_control_destroy(window->control);
     556        ui_menu_destroy(window->sysmenu);
    393557        ui_wdecor_destroy(window->wdecor);
    394558        ui_resource_destroy(window->res);
    395         if (0 && window->app_mgc != NULL)
     559        if (window->app_mgc != NULL)
    396560                mem_gc_delete(window->app_mgc);
    397         if (0 && window->app_bmp != NULL)
     561        if (window->app_bmp != NULL)
    398562                gfx_bitmap_destroy(window->app_bmp);
    399563        if (window->mgc != NULL) {
     
    406570                display_window_destroy(window->dwindow);
    407571
    408         free(window);
    409 
    410572        /* Need to repaint if windows are emulated */
    411573        if (ui_is_fullscreen(ui)) {
    412574                ui_paint(ui);
    413         }
     575                /* Send focus event to newly active window */
     576                nwindow = ui_window_get_active(ui);
     577                if (nwindow != NULL)
     578                        ui_window_send_focus(nwindow, 0);
     579        }
     580
     581        if (ui->console != NULL &&
     582            window->placement == ui_wnd_place_full_screen) {
     583                (void) console_set_caption(ui->console, "");
     584        }
     585
     586        free(window);
    414587}
    415588
     
    421594 * @param window Window
    422595 * @param control Control
    423  * @return EOK on success, ENOMEM if out of memory
    424596 */
    425597void ui_window_add(ui_window_t *window, ui_control_t *control)
     
    461633}
    462634
    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.
     635/** Resize or (un)maximize window.
    467636 *
    468637 * @param window Window
    469638 * @param rect Rectangle
     639 * @param scop Size change operation
    470640 *
    471641 * @return EOK on success or an error code
    472642 */
    473 errno_t ui_window_resize(ui_window_t *window, gfx_rect_t *rect)
     643errno_t ui_window_size_change(ui_window_t *window, gfx_rect_t *rect,
     644    ui_wnd_sc_op_t scop)
    474645{
    475646        gfx_coord2_t offs;
     
    537708        }
    538709
    539         /* dwindow can be NULL in case of unit tests */
     710        /* dwindow can be NULL in case of unit tests or fullscreen mode */
    540711        if (window->dwindow != NULL) {
    541                 rc = display_window_resize(window->dwindow, &offs, &nrect);
    542                 if (rc != EOK)
    543                         goto error;
     712                switch (scop) {
     713                case ui_wsc_resize:
     714                        rc = display_window_resize(window->dwindow, &offs,
     715                            &nrect);
     716                        if (rc != EOK)
     717                                goto error;
     718                        break;
     719                case ui_wsc_maximize:
     720                        rc = display_window_maximize(window->dwindow);
     721                        if (rc != EOK)
     722                                goto error;
     723                        break;
     724                case ui_wsc_unmaximize:
     725                        rc = display_window_unmaximize(window->dwindow);
     726                        if (rc != EOK)
     727                                goto error;
     728                        break;
     729                }
    544730        }
    545731
     
    561747                        goto error;
    562748#endif
    563 
    564749                mem_gc_retarget(window->mgc, &win_params.rect, &win_alloc);
    565750
     
    568753        }
    569754
     755        window->rect = nrect;
    570756        ui_wdecor_set_rect(window->wdecor, &nrect);
    571757        ui_wdecor_paint(window->wdecor);
     
    589775}
    590776
     777/** Resize/move window.
     778 *
     779 * Resize window to the dimensions of @a rect. If @a rect.p0 is not 0,0,
     780 * the top-left corner of the window will move on the screen accordingly.
     781 *
     782 * @param window Window
     783 * @param rect Rectangle
     784 *
     785 * @return EOK on success or an error code
     786 */
     787errno_t ui_window_resize(ui_window_t *window, gfx_rect_t *rect)
     788{
     789        return ui_window_size_change(window, rect, ui_wsc_resize);
     790}
     791
    591792/** Set window callbacks.
    592793 *
     
    599800        window->cb = cb;
    600801        window->arg = arg;
     802}
     803
     804/** Change window caption.
     805 *
     806 * @param window Window
     807 * @param caption New caption
     808 *
     809 * @return EOK on success or an error code
     810 */
     811errno_t ui_window_set_caption(ui_window_t *window, const char *caption)
     812{
     813        errno_t rc;
     814
     815        /* Set console caption if fullscreen window on console */
     816        if (window->ui->console != NULL && window->placement ==
     817            ui_wnd_place_full_screen) {
     818                rc = console_set_caption(window->ui->console, caption);
     819                if (rc != EOK)
     820                        return rc;
     821        }
     822
     823        /* Set display window caption if running on display service */
     824        if (window->dwindow != NULL) {
     825                rc = display_window_set_caption(window->dwindow, caption);
     826                if (rc != EOK)
     827                        return rc;
     828        }
     829
     830        return ui_wdecor_set_caption(window->wdecor, caption);
    601831}
    602832
     
    746976{
    747977        ui_window_t *window = (ui_window_t *) arg;
    748 
     978        ui_t *ui = window->ui;
     979
     980        ui_lock(ui);
    749981        ui_window_send_close(window);
     982        ui_unlock(ui);
    750983}
    751984
    752985/** Handle window focus event. */
    753 static void dwnd_focus_event(void *arg)
    754 {
    755         ui_window_t *window = (ui_window_t *) arg;
     986static void dwnd_focus_event(void *arg, unsigned nfocus)
     987{
     988        ui_window_t *window = (ui_window_t *) arg;
     989        ui_t *ui = window->ui;
     990
     991        ui_lock(ui);
     992        (void)nfocus;
    756993
    757994        if (window->wdecor != NULL) {
     
    760997        }
    761998
    762         ui_window_send_focus(window);
     999        ui_window_send_focus(window, nfocus);
     1000        ui_unlock(ui);
    7631001}
    7641002
     
    7671005{
    7681006        ui_window_t *window = (ui_window_t *) arg;
    769 
    770         (void) window;
     1007        ui_t *ui = window->ui;
     1008
     1009        ui_lock(ui);
    7711010        ui_window_send_kbd(window, kbd_event);
     1011        ui_unlock(ui);
    7721012}
    7731013
     
    7761016{
    7771017        ui_window_t *window = (ui_window_t *) arg;
     1018        ui_t *ui = window->ui;
     1019        ui_evclaim_t claim;
    7781020
    7791021        /* Make sure we don't process events until fully initialized */
     
    7811023                return;
    7821024
    783         ui_wdecor_pos_event(window->wdecor, event);
     1025        ui_lock(ui);
     1026
     1027        claim = ui_wdecor_pos_event(window->wdecor, event);
     1028        if (claim == ui_claimed) {
     1029                ui_unlock(ui);
     1030                return;
     1031        }
     1032
    7841033        ui_window_send_pos(window, event);
     1034        ui_unlock(ui);
    7851035}
    7861036
     
    7891039{
    7901040        ui_window_t *window = (ui_window_t *) arg;
     1041        ui_t *ui = window->ui;
    7911042
    7921043        /* Make sure we don't process events until fully initialized */
     
    7971048                return;
    7981049
     1050        ui_lock(ui);
    7991051        (void) ui_window_resize(window, rect);
    800         (void) ui_window_paint(window);
     1052        ui_window_send_resize(window);
     1053        ui_unlock(ui);
    8011054}
    8021055
    8031056/** 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) {
     1057static void dwnd_unfocus_event(void *arg, unsigned nfocus)
     1058{
     1059        ui_window_t *window = (ui_window_t *) arg;
     1060        ui_t *ui = window->ui;
     1061
     1062        ui_lock(ui);
     1063
     1064        if (window->wdecor != NULL && nfocus == 0) {
    8091065                ui_wdecor_set_active(window->wdecor, false);
    8101066                ui_wdecor_paint(window->wdecor);
    8111067        }
    8121068
    813         ui_window_send_unfocus(window);
     1069        ui_window_send_unfocus(window, nfocus);
     1070        ui_unlock(ui);
     1071}
     1072
     1073/** Window decoration requested opening of system menu.
     1074 *
     1075 * @param wdecor Window decoration
     1076 * @param arg Argument (window)
     1077 * @param idev_id Input device ID
     1078 */
     1079static void wd_sysmenu_open(ui_wdecor_t *wdecor, void *arg, sysarg_t idev_id)
     1080{
     1081        ui_window_t *window = (ui_window_t *) arg;
     1082
     1083        ui_window_send_sysmenu(window, idev_id);
     1084}
     1085
     1086/** Window decoration requested moving left from system menu handle.
     1087 *
     1088 * @param wdecor Window decoration
     1089 * @param arg Argument (window)
     1090 * @param idev_id Input device ID
     1091 */
     1092static void wd_sysmenu_left(ui_wdecor_t *wdecor, void *arg, sysarg_t idev_id)
     1093{
     1094        ui_window_t *window = (ui_window_t *) arg;
     1095
     1096        if (window->mbar != NULL) {
     1097                ui_wdecor_sysmenu_hdl_set_active(window->wdecor, false);
     1098                ui_menu_close(window->sysmenu);
     1099                ui_menu_bar_select_last(window->mbar, false, idev_id);
     1100        }
     1101}
     1102
     1103/** Window decoration requested moving right from system menu handle.
     1104 *
     1105 * @param wdecor Window decoration
     1106 * @param arg Argument (window)
     1107 * @param idev_id Input device ID
     1108 */
     1109static void wd_sysmenu_right(ui_wdecor_t *wdecor, void *arg, sysarg_t idev_id)
     1110{
     1111        ui_window_t *window = (ui_window_t *) arg;
     1112
     1113        if (window->mbar != NULL) {
     1114                ui_wdecor_sysmenu_hdl_set_active(window->wdecor, false);
     1115                ui_menu_close(window->sysmenu);
     1116                ui_menu_bar_select_first(window->mbar, false, idev_id);
     1117        }
     1118}
     1119
     1120/** Window decoration detected accelerator press from system menu handle.
     1121 *
     1122 * @param wdecor Window decoration
     1123 * @param arg Argument (window)
     1124 * @param c Accelerator key
     1125 * @param idev_id Input device ID
     1126 */
     1127static void wd_sysmenu_accel(ui_wdecor_t *wdecor, void *arg, char32_t c,
     1128    sysarg_t idev_id)
     1129{
     1130        ui_window_t *window = (ui_window_t *) arg;
     1131
     1132        if (window->mbar != NULL) {
     1133                ui_wdecor_sysmenu_hdl_set_active(window->wdecor, false);
     1134                ui_menu_close(window->sysmenu);
     1135                ui_menu_bar_press_accel(window->mbar, c, idev_id);
     1136        }
     1137}
     1138
     1139/** Window decoration requested window minimization.
     1140 *
     1141 * @param wdecor Window decoration
     1142 * @param arg Argument (window)
     1143 */
     1144static void wd_minimize(ui_wdecor_t *wdecor, void *arg)
     1145{
     1146        ui_window_t *window = (ui_window_t *) arg;
     1147
     1148        ui_window_send_minimize(window);
     1149}
     1150
     1151/** Window decoration requested window maximization.
     1152 *
     1153 * @param wdecor Window decoration
     1154 * @param arg Argument (window)
     1155 */
     1156static void wd_maximize(ui_wdecor_t *wdecor, void *arg)
     1157{
     1158        ui_window_t *window = (ui_window_t *) arg;
     1159
     1160        ui_window_send_maximize(window);
     1161}
     1162
     1163/** Window decoration requested window unmaximization.
     1164 *
     1165 * @param wdecor Window decoration
     1166 * @param arg Argument (window)
     1167 */
     1168static void wd_unmaximize(ui_wdecor_t *wdecor, void *arg)
     1169{
     1170        ui_window_t *window = (ui_window_t *) arg;
     1171
     1172        ui_window_send_unmaximize(window);
    8141173}
    8151174
     
    8311190 * @param arg Argument (window)
    8321191 * @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)
     1192 * @param pos_id Positioning device ID
     1193 */
     1194static void wd_move(ui_wdecor_t *wdecor, void *arg, gfx_coord2_t *pos,
     1195    sysarg_t pos_id)
    8351196{
    8361197        ui_window_t *window = (ui_window_t *) arg;
    8371198
    8381199        if (window->dwindow != NULL)
    839                 (void) display_window_move_req(window->dwindow, pos);
     1200                (void) display_window_move_req(window->dwindow, pos, pos_id);
    8401201}
    8411202
     
    8461207 * @param rsztype Resize type
    8471208 * @param pos Position where the button was pressed
     1209 * @param pos_id Positioning device ID
    8481210 */
    8491211static 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);
     1212    ui_wdecor_rsztype_t rsztype, gfx_coord2_t *pos, sysarg_t pos_id)
     1213{
     1214        ui_window_t *window = (ui_window_t *) arg;
     1215
     1216        if (window->dwindow != NULL) {
     1217                (void) display_window_resize_req(window->dwindow,
     1218                    (display_wnd_rsztype_t) rsztype, // Same constants in the enums
     1219                    pos, pos_id);
     1220        }
    8561221}
    8571222
     
    9141279}
    9151280
     1281/** Send window sysmenu event.
     1282 *
     1283 * @param window Window
     1284 * @parma idev_id Input device ID
     1285 */
     1286void ui_window_send_sysmenu(ui_window_t *window, sysarg_t idev_id)
     1287{
     1288        if (window->cb != NULL && window->cb->sysmenu != NULL)
     1289                window->cb->sysmenu(window, window->arg, idev_id);
     1290        else
     1291                ui_window_def_sysmenu(window, idev_id);
     1292}
     1293
     1294/** Send window minimize event.
     1295 *
     1296 * @param window Window
     1297 */
     1298void ui_window_send_minimize(ui_window_t *window)
     1299{
     1300        if (window->cb != NULL && window->cb->minimize != NULL)
     1301                window->cb->minimize(window, window->arg);
     1302        else
     1303                ui_window_def_minimize(window);
     1304}
     1305
     1306/** Send window maximize event.
     1307 *
     1308 * @param window Window
     1309 */
     1310void ui_window_send_maximize(ui_window_t *window)
     1311{
     1312        if (window->cb != NULL && window->cb->maximize != NULL)
     1313                window->cb->maximize(window, window->arg);
     1314        else
     1315                ui_window_def_maximize(window);
     1316}
     1317
     1318/** Send window unmaximize event.
     1319 *
     1320 * @param window Window
     1321 */
     1322void ui_window_send_unmaximize(ui_window_t *window)
     1323{
     1324        if (window->cb != NULL && window->cb->unmaximize != NULL)
     1325                window->cb->unmaximize(window, window->arg);
     1326        else
     1327                ui_window_def_unmaximize(window);
     1328}
     1329
    9161330/** Send window close event.
    9171331 *
     
    9271341 *
    9281342 * @param window Window
    929  */
    930 void ui_window_send_focus(ui_window_t *window)
     1343 * @param nfocus New number of foci
     1344 */
     1345void ui_window_send_focus(ui_window_t *window, unsigned nfocus)
    9311346{
    9321347        if (window->cb != NULL && window->cb->focus != NULL)
    933                 window->cb->focus(window, window->arg);
     1348                window->cb->focus(window, window->arg, nfocus);
    9341349}
    9351350
     
    9431358                window->cb->kbd(window, window->arg, kbd);
    9441359        else
    945                 return ui_window_def_kbd(window, kbd);
     1360                ui_window_def_kbd(window, kbd);
    9461361}
    9471362
     
    9731388 *
    9741389 * @param window Window
    975  */
    976 void ui_window_send_unfocus(ui_window_t *window)
     1390 * @param nfocus Number of remaining foci
     1391 */
     1392void ui_window_send_unfocus(ui_window_t *window, unsigned nfocus)
    9771393{
    9781394        if (window->cb != NULL && window->cb->unfocus != NULL)
    979                 window->cb->unfocus(window, window->arg);
     1395                window->cb->unfocus(window, window->arg, nfocus);
    9801396        else
    981                 return ui_window_def_unfocus(window);
     1397                return ui_window_def_unfocus(window, nfocus);
     1398}
     1399
     1400/** Send window resize event.
     1401 *
     1402 * @param window Window
     1403 */
     1404void ui_window_send_resize(ui_window_t *window)
     1405{
     1406        if (window->cb != NULL && window->cb->resize != NULL)
     1407                window->cb->resize(window, window->arg);
     1408        else
     1409                return ui_window_def_resize(window);
     1410}
     1411
     1412/** Default window sysmenu routine.
     1413 *
     1414 * @param window Window
     1415 * @param idev_id Input device ID
     1416 * @return EOK on success or an error code
     1417 */
     1418errno_t ui_window_def_sysmenu(ui_window_t *window, sysarg_t idev_id)
     1419{
     1420        errno_t rc;
     1421        ui_wdecor_geom_t geom;
     1422
     1423        if (ui_menu_is_open(window->sysmenu)) {
     1424                ui_menu_close(window->sysmenu);
     1425        } else {
     1426                ui_wdecor_get_geom(window->wdecor, &geom);
     1427
     1428                rc = ui_menu_open(window->sysmenu, &geom.title_bar_rect,
     1429                    idev_id);
     1430                if (rc != EOK)
     1431                        goto error;
     1432        }
     1433
     1434        return EOK;
     1435error:
     1436        return rc;
     1437}
     1438
     1439/** Default window minimize routine.
     1440 *
     1441 * @param window Window
     1442 * @return EOK on success or an error code
     1443 */
     1444errno_t ui_window_def_minimize(ui_window_t *window)
     1445{
     1446        errno_t rc;
     1447
     1448        if (window->dwindow != NULL) {
     1449                rc = display_window_minimize(window->dwindow);
     1450                if (rc != EOK)
     1451                        goto error;
     1452        }
     1453
     1454        return EOK;
     1455error:
     1456        return rc;
     1457}
     1458
     1459/** Default window maximize routine.
     1460 *
     1461 * @param window Window
     1462 * @return EOK on success or an error code
     1463 */
     1464errno_t ui_window_def_maximize(ui_window_t *window)
     1465{
     1466        errno_t rc;
     1467        gfx_rect_t old_rect;
     1468        gfx_rect_t rect;
     1469
     1470        old_rect = window->rect;
     1471
     1472        if (window->dwindow != NULL) {
     1473                rc = display_window_get_max_rect(window->dwindow, &rect);
     1474                if (rc != EOK)
     1475                        return rc;
     1476        } else {
     1477                rect = window->ui->rect;
     1478        }
     1479
     1480        ui_wdecor_set_maximized(window->wdecor, true);
     1481        ui_menu_entry_set_disabled(window->sysmenu_restore, false);
     1482        ui_menu_entry_set_disabled(window->sysmenu_maximize, true);
     1483
     1484        rc = ui_window_size_change(window, &rect, ui_wsc_maximize);
     1485        if (rc != EOK) {
     1486                ui_wdecor_set_maximized(window->wdecor, false);
     1487                return rc;
     1488        }
     1489
     1490        window->normal_rect = old_rect;
     1491        (void) ui_window_paint(window);
     1492        return EOK;
     1493}
     1494
     1495/** Default window unmaximize routine.
     1496 *
     1497 * @param window Window
     1498 * @return EOK on success or an error code
     1499 */
     1500errno_t ui_window_def_unmaximize(ui_window_t *window)
     1501{
     1502        errno_t rc;
     1503
     1504        ui_wdecor_set_maximized(window->wdecor, false);
     1505        ui_menu_entry_set_disabled(window->sysmenu_restore, true);
     1506        ui_menu_entry_set_disabled(window->sysmenu_maximize, false);
     1507
     1508        rc = ui_window_size_change(window, &window->normal_rect,
     1509            ui_wsc_unmaximize);
     1510        if (rc != EOK) {
     1511                ui_wdecor_set_maximized(window->wdecor, true);
     1512                printf("ui_window_size_change->error\n");
     1513                return rc;
     1514        }
     1515
     1516        (void) ui_window_paint(window);
     1517        return EOK;
    9821518}
    9831519
     
    9851521 *
    9861522 * @param window Window
    987  */
    988 void ui_window_def_kbd(ui_window_t *window, kbd_event_t *kbd)
    989 {
     1523 * @return ui_claimed iff event was claimed
     1524 */
     1525ui_evclaim_t ui_window_def_kbd(ui_window_t *window, kbd_event_t *kbd)
     1526{
     1527        ui_evclaim_t claim;
     1528
    9901529        if (window->control != NULL)
    991                 ui_control_kbd_event(window->control, kbd);
     1530                claim = ui_control_kbd_event(window->control, kbd);
     1531        else
     1532                claim = ui_unclaimed;
     1533
     1534        if (claim == ui_unclaimed)
     1535                return ui_wdecor_kbd_event(window->wdecor, kbd);
     1536
     1537        return ui_unclaimed;
    9921538}
    9931539
     
    10351581 *
    10361582 * @param window Window
     1583 * @param nfocus Number of remaining foci
    10371584 * @return EOK on success or an error code
    10381585 */
    1039 void ui_window_def_unfocus(ui_window_t *window)
     1586void ui_window_def_unfocus(ui_window_t *window, unsigned nfocus)
    10401587{
    10411588        if (window->control != NULL)
    1042                 ui_control_unfocus(window->control);
     1589                ui_control_unfocus(window->control, nfocus);
     1590}
     1591
     1592/** Default window resize routine.
     1593 *
     1594 * @param window Window
     1595 * @return EOK on success or an error code
     1596 */
     1597void ui_window_def_resize(ui_window_t *window)
     1598{
     1599        ui_window_paint(window);
     1600}
     1601
     1602/** Handle system menu left event.
     1603 *
     1604 * @param sysmenu System menu
     1605 * @param arg Argument (ui_window_t *)
     1606 * @param idev_id Input device ID
     1607 */
     1608static void wnd_sysmenu_left(ui_menu_t *sysmenu, void *arg, sysarg_t idev_id)
     1609{
     1610        ui_window_t *window = (ui_window_t *)arg;
     1611
     1612        if (window->mbar != NULL) {
     1613                ui_wdecor_sysmenu_hdl_set_active(window->wdecor, false);
     1614                ui_menu_close(sysmenu);
     1615                ui_menu_bar_select_last(window->mbar, true, idev_id);
     1616        }
     1617}
     1618
     1619/** Handle system menu right event.
     1620 *
     1621 * @param sysmenu System menu
     1622 * @param arg Argument (ui_window_t *)
     1623 * @param idev_id Input device ID
     1624 */
     1625static void wnd_sysmenu_right(ui_menu_t *sysmenu, void *arg, sysarg_t idev_id)
     1626{
     1627        ui_window_t *window = (ui_window_t *)arg;
     1628
     1629        if (window->mbar != NULL) {
     1630                ui_wdecor_sysmenu_hdl_set_active(window->wdecor, false);
     1631                ui_menu_close(sysmenu);
     1632                ui_menu_bar_select_first(window->mbar, true, idev_id);
     1633        }
     1634}
     1635
     1636/** Handle system menu close request event.
     1637 *
     1638 * @param sysmenu System menu
     1639 * @param arg Argument (ui_window_t *)
     1640 * @param idev_id Input device ID
     1641 */
     1642static void wnd_sysmenu_close_req(ui_menu_t *sysmenu, void *arg)
     1643{
     1644        ui_window_t *window = (ui_window_t *)arg;
     1645
     1646        ui_wdecor_sysmenu_hdl_set_active(window->wdecor, false);
     1647        ui_menu_close(sysmenu);
     1648}
     1649
     1650/** Handle system menu Restore entry activation.
     1651 *
     1652 * @param mentry Menu entry
     1653 * @param arg Argument (ui_window_t *)
     1654 */
     1655static void wnd_sysmenu_erestore(ui_menu_entry_t *mentry, void *arg)
     1656{
     1657        ui_window_t *window = (ui_window_t *)arg;
     1658
     1659        ui_window_send_unmaximize(window);
     1660}
     1661
     1662/** Handle system menu Minimize entry activation.
     1663 *
     1664 * @param mentry Menu entry
     1665 * @param arg Argument (ui_window_t *)
     1666 */
     1667static void wnd_sysmenu_eminimize(ui_menu_entry_t *mentry, void *arg)
     1668{
     1669        ui_window_t *window = (ui_window_t *)arg;
     1670
     1671        ui_window_send_minimize(window);
     1672}
     1673
     1674/** Handle system menu Maximize entry activation.
     1675 *
     1676 * @param mentry Menu entry
     1677 * @param arg Argument (ui_window_t *)
     1678 */
     1679static void wnd_sysmenu_emaximize(ui_menu_entry_t *mentry, void *arg)
     1680{
     1681        ui_window_t *window = (ui_window_t *)arg;
     1682
     1683        ui_window_send_maximize(window);
     1684}
     1685
     1686/** Handle system menu Close entry activation.
     1687 *
     1688 * @param mentry Menu entry
     1689 * @param arg Argument (ui_window_t *)
     1690 */
     1691static void wnd_sysmenu_eclose(ui_menu_entry_t *mentry, void *arg)
     1692{
     1693        ui_window_t *window = (ui_window_t *)arg;
     1694
     1695        ui_window_send_close(window);
     1696}
     1697
     1698/** Handle system menu press accelerator key event.
     1699 *
     1700 * @param sysmenu System menu
     1701 * @param arg Argument (ui_window_t *)
     1702 * @param idev_id Input device ID
     1703 */
     1704static void wnd_sysmenu_press_accel(ui_menu_t *sysmenu, void *arg,
     1705    char32_t c, sysarg_t idev_id)
     1706{
     1707        (void)sysmenu;
     1708        (void)arg;
     1709        (void)c;
     1710        (void)idev_id;
    10431711}
    10441712
Note: See TracChangeset for help on using the changeset viewer.