Changeset ee3b28a9 in mainline


Ignore:
Timestamp:
2024-02-26T13:30:48Z (2 months ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
master
Children:
d92b8e8f
Parents:
90ba06c
git-author:
Jiri Svoboda <jiri@…> (2024-02-25 16:12:29)
git-committer:
Jiri Svoboda <jiri@…> (2024-02-26 13:30:48)
Message:

Notify taskbar when start menu changes

Files:
1 added
15 edited

Legend:

Unmodified
Added
Removed
  • abi/include/abi/ipc/interfaces.h

    r90ba06c ree3b28a9  
    11/*
    2  * Copyright (c) 2023 Jiri Svoboda
     2 * Copyright (c) 2024 Jiri Svoboda
    33 * Copyright (c) 2014 Martin Decky
    44 * All rights reserved.
     
    201201        INTERFACE_WNDMGT_CB =
    202202            FOURCC_COMPACT('w', 'm', 'g', 't') | IFACE_EXCHANGE_SERIALIZE | IFACE_MOD_CALLBACK,
     203        INTERFACE_TBARCFG_NOTIFY =
     204            FOURCC_COMPACT('t', 'b', 'c', 'f') | IFACE_EXCHANGE_SERIALIZE
    203205} iface_t;
    204206
  • uspace/app/taskbar-cfg/smeedit.c

    r90ba06c ree3b28a9  
    403403
    404404                startmenu_repaint(smee->startmenu);
     405                (void)tbarcfg_notify(TBARCFG_NOTIFY_DEFAULT);
    405406        } else {
    406407                /* Edit existing entry */
     
    419420                (void)smenu_entry_save(smee->smentry->entry);
    420421                startmenu_entry_update(smee->smentry);
     422                (void)tbarcfg_notify(TBARCFG_NOTIFY_DEFAULT);
    421423        }
    422424
  • uspace/app/taskbar-cfg/startmenu.c

    r90ba06c ree3b28a9  
    515515
    516516        (void)smee;
     517        (void)tbarcfg_notify(TBARCFG_NOTIFY_DEFAULT);
    517518}
    518519
     
    533534        (void)startmenu_insert(smenu, entry, &smentry);
    534535        (void)ui_control_paint(ui_list_ctl(smenu->entries_list));
     536        (void)tbarcfg_notify(TBARCFG_NOTIFY_DEFAULT);
    535537}
    536538
     
    633635        free(smentry);
    634636        (void)ui_control_paint(ui_list_ctl(smenu->entries_list));
     637        (void)tbarcfg_notify(TBARCFG_NOTIFY_DEFAULT);
    635638}
    636639
     
    685688
    686689        (void)ui_control_paint(ui_list_ctl(smenu->entries_list));
     690        (void)tbarcfg_notify(TBARCFG_NOTIFY_DEFAULT);
    687691}
    688692
     
    711715
    712716        (void)ui_control_paint(ui_list_ctl(smenu->entries_list));
     717        (void)tbarcfg_notify(TBARCFG_NOTIFY_DEFAULT);
    713718}
    714719
  • uspace/app/taskbar/taskbar.c

    r90ba06c ree3b28a9  
    11/*
    2  * Copyright (c) 2023 Jiri Svoboda
     2 * Copyright (c) 2024 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    4848#include "wndlist.h"
    4949
     50#define TASKBAR_CONFIG_FILE "/cfg/taskbar.sif"
     51
    5052static void taskbar_wnd_close(ui_window_t *, void *);
    5153static void taskbar_wnd_kbd(ui_window_t *, void *, kbd_event_t *);
    5254static void taskbar_wnd_pos(ui_window_t *, void *, pos_event_t *);
     55static void taskbar_notif_cb(void *);
    5356
    5457static ui_window_cb_t window_cb = {
     
    201204        }
    202205
    203         rc = tbsmenu_load(taskbar->tbsmenu, "/cfg/taskbar.sif");
     206        rc = tbsmenu_load(taskbar->tbsmenu, TASKBAR_CONFIG_FILE);
    204207        if (rc != EOK) {
    205208                printf("Error loading start menu from '%s'.\n",
    206                     "/cfg/taskbar.sif");
     209                    TASKBAR_CONFIG_FILE);
     210        }
     211
     212        rc = tbarcfg_listener_create(TBARCFG_NOTIFY_DEFAULT,
     213            taskbar_notif_cb, (void *)taskbar, &taskbar->lst);
     214        if (rc != EOK) {
     215                printf("Error listening for configuration changes.\n");
    207216        }
    208217
     
    287296        return EOK;
    288297error:
     298        if (taskbar->lst != NULL)
     299                tbarcfg_listener_destroy(taskbar->lst);
    289300        if (taskbar->clock != NULL)
    290301                taskbar_clock_destroy(taskbar->clock);
     
    304315void taskbar_destroy(taskbar_t *taskbar)
    305316{
     317        if (taskbar->lst != NULL)
     318                tbarcfg_listener_destroy(taskbar->lst);
    306319        ui_fixed_remove(taskbar->fixed, taskbar_clock_ctl(taskbar->clock));
    307320        taskbar_clock_destroy(taskbar->clock);
     
    312325}
    313326
     327/** Configuration change notification callback.
     328 *
     329 * Called when configuration changed.
     330 *
     331 * @param arg Argument (taskbar_t *)
     332 */
     333static void taskbar_notif_cb(void *arg)
     334{
     335        taskbar_t *taskbar = (taskbar_t *)arg;
     336
     337        ui_lock(taskbar->ui);
     338        tbsmenu_reload(taskbar->tbsmenu);
     339        ui_unlock(taskbar->ui);
     340}
     341
    314342/** @}
    315343 */
  • uspace/app/taskbar/tbsmenu.c

    r90ba06c ree3b28a9  
    135135        errno_t rc;
    136136
     137        if (tbsmenu->repopath != NULL)
     138                free(tbsmenu->repopath);
     139
     140        tbsmenu->repopath = str_dup(repopath);
     141        if (tbsmenu->repopath == NULL)
     142                return ENOMEM;
     143
     144        /* Remove existing entries */
     145        tentry = tbsmenu_first(tbsmenu);
     146        while (tentry != NULL) {
     147                tbsmenu_remove(tbsmenu, tentry, false);
     148                tentry = tbsmenu_first(tbsmenu);
     149        }
     150
    137151        rc = tbarcfg_open(repopath, &tbcfg);
    138152        if (rc != EOK)
     
    170184}
    171185
     186/** Reload start menu from repository (or schedule reload).
     187 *
     188 * @param tbsmenu Start menu
     189 */
     190void tbsmenu_reload(tbsmenu_t *tbsmenu)
     191{
     192        if (!tbsmenu_is_open(tbsmenu))
     193                (void) tbsmenu_load(tbsmenu, tbsmenu->repopath);
     194        else
     195                tbsmenu->needs_reload = true;
     196}
     197
    172198/** Set start menu rectangle.
    173199 *
     
    198224{
    199225        ui_menu_close(tbsmenu->smenu);
     226
     227        if (tbsmenu->needs_reload)
     228                (void) tbsmenu_load(tbsmenu, tbsmenu->repopath);
    200229}
    201230
  • uspace/app/taskbar/tbsmenu.h

    r90ba06c ree3b28a9  
    4848extern errno_t tbsmenu_create(ui_window_t *, ui_fixed_t *, tbsmenu_t **);
    4949extern errno_t tbsmenu_load(tbsmenu_t *, const char *);
     50extern void tbsmenu_reload(tbsmenu_t *);
    5051extern void tbsmenu_set_rect(tbsmenu_t *, gfx_rect_t *);
    5152extern void tbsmenu_open(tbsmenu_t *);
  • uspace/app/taskbar/types/taskbar.h

    r90ba06c ree3b28a9  
    11/*
    2  * Copyright (c) 2023 Jiri Svoboda
     2 * Copyright (c) 2024 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    6060        /** Clock */
    6161        taskbar_clock_t *clock;
     62        /** Configuration change listener */
     63        tbarcfg_listener_t *lst;
    6264} taskbar_t;
    6365
  • uspace/app/taskbar/types/tbsmenu.h

    r90ba06c ree3b28a9  
    4040#include <gfx/coord.h>
    4141#include <stdbool.h>
     42#include <tbarcfg/tbarcfg.h>
    4243#include <ui/pbutton.h>
    4344#include <ui/fixed.h>
     
    8485        /** Device ID of last input event */
    8586        sysarg_t ev_idev_id;
     87
     88        /** Repository path name */
     89        char *repopath;
     90
     91        /** Need to reload menu when possible */
     92        bool needs_reload;
    8693} tbsmenu_t;
    8794
  • uspace/lib/tbarcfg/include/tbarcfg/tbarcfg.h

    r90ba06c ree3b28a9  
    4242#include <types/tbarcfg/tbarcfg.h>
    4343
     44#define TBARCFG_NOTIFY_DEFAULT "tbarcfg-notif"
     45
    4446extern errno_t tbarcfg_create(const char *, tbarcfg_t **);
    4547extern errno_t tbarcfg_open(const char *, tbarcfg_t **);
     
    6365extern errno_t smenu_entry_move_up(smenu_entry_t *);
    6466extern errno_t smenu_entry_move_down(smenu_entry_t *);
     67extern errno_t tbarcfg_listener_create(const char *, void (*)(void *),
     68    void *, tbarcfg_listener_t **);
     69extern void tbarcfg_listener_destroy(tbarcfg_listener_t *);
     70extern errno_t tbarcfg_notify(const char *);
    6571
    6672#endif
  • uspace/lib/tbarcfg/include/types/tbarcfg/tbarcfg.h

    r90ba06c ree3b28a9  
    11/*
    2  * Copyright (c) 2023 Jiri Svoboda
     2 * Copyright (c) 2024 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    4343typedef struct smenu_entry smenu_entry_t;
    4444
     45struct tbarcfg_listener;
     46typedef struct tbarcfg_listener tbarcfg_listener_t;
     47
    4548#endif
    4649
  • uspace/lib/tbarcfg/private/tbarcfg.h

    r90ba06c ree3b28a9  
    7171};
    7272
     73/** Taskbar configuration listener */
     74typedef struct tbarcfg_listener {
     75        /** Notification callback */
     76        void (*cb)(void *);
     77        /** Callback argument */
     78        void *arg;
     79} tbarcfg_listener_t;
     80
    7381extern errno_t smenu_entry_new(tbarcfg_t *, sif_node_t *, const char *,
    7482    const char *, bool, smenu_entry_t **);
  • uspace/lib/tbarcfg/src/tbarcfg.c

    r90ba06c ree3b28a9  
    3434 */
    3535
     36#include <async.h>
    3637#include <errno.h>
    3738#include <sif.h>
     39#include <ipc/tbarcfg.h>
     40#include <loc.h>
     41#include <task.h>
    3842#include <tbarcfg/tbarcfg.h>
     43#include <stdio.h>
    3944#include <stdlib.h>
    4045#include <str.h>
    4146#include "../private/tbarcfg.h"
     47
     48static void tbarcfg_notify_conn(ipc_call_t *, void *);
    4249
    4350/** Create taskbar configuration.
     
    784791}
    785792
     793/** Create taskbar configuration listener.
     794 *
     795 * Listens for taskbar configuration change notifications.
     796 *
     797 * @param nchan Notification channel (TBARCFG_NOTIFY_DEFAULT)
     798 * @param rlst Place to store pointer to new listener
     799 * @return EOK on success or an error code
     800 */
     801errno_t tbarcfg_listener_create(const char *nchan, void (*cb)(void *),
     802    void *arg, tbarcfg_listener_t **rlst)
     803{
     804        tbarcfg_listener_t *lst;
     805        service_id_t svcid = 0;
     806        loc_srv_t *srv = NULL;
     807        task_id_t taskid;
     808        char *svcname = NULL;
     809        category_id_t catid;
     810        port_id_t port;
     811        int rv;
     812        errno_t rc;
     813
     814        lst = calloc(1, sizeof(tbarcfg_listener_t));
     815        if (lst == NULL)
     816                return ENOMEM;
     817
     818        lst->cb = cb;
     819        lst->arg = arg;
     820
     821        rc = async_create_port(INTERFACE_TBARCFG_NOTIFY,
     822            tbarcfg_notify_conn, (void *)lst, &port);
     823        if (rc != EOK)
     824                goto error;
     825
     826        rc = loc_server_register("tbarcfg-listener", &srv);
     827        if (rc != EOK)
     828                goto error;
     829
     830        taskid = task_get_id();
     831
     832        rv = asprintf(&svcname, "tbarcfg/%u", (unsigned)taskid);
     833        if (rv < 0) {
     834                rc = ENOMEM;
     835                goto error;
     836        }
     837
     838        rc = loc_service_register(srv, svcname, &svcid);
     839        if (rc != EOK)
     840                goto error;
     841
     842        rc = loc_category_get_id(nchan, &catid, 0);
     843        if (rc != EOK)
     844                goto error;
     845
     846        rc = loc_service_add_to_cat(srv, svcid, catid);
     847        if (rc != EOK)
     848                goto error;
     849
     850        *rlst = lst;
     851        return EOK;
     852error:
     853        if (svcid != 0)
     854                loc_service_unregister(srv, svcid);
     855        if (srv != NULL)
     856                loc_server_unregister(srv);
     857        if (svcname != NULL)
     858                free(svcname);
     859        return rc;
     860}
     861
     862/** Destroy taskbar configuration listener.
     863 *
     864 * @param lst Listener
     865 */
     866void tbarcfg_listener_destroy(tbarcfg_listener_t *lst)
     867{
     868        free(lst);
     869}
     870
     871/** Send taskbar configuration notification to a particular service ID.
     872 *
     873 * @param svcid Service ID
     874 * @return EOK on success or an error code
     875 */
     876static errno_t tbarcfg_notify_svc(service_id_t svcid)
     877{
     878        async_sess_t *sess;
     879        async_exch_t *exch;
     880        errno_t rc;
     881
     882        sess = loc_service_connect(svcid, INTERFACE_TBARCFG_NOTIFY, 0);
     883        if (sess == NULL)
     884                return EIO;
     885
     886        exch = async_exchange_begin(sess);
     887        rc = async_req_0_0(exch, TBARCFG_NOTIFY_NOTIFY);
     888        if (rc != EOK) {
     889                async_exchange_end(exch);
     890                async_hangup(sess);
     891                return rc;
     892        }
     893
     894        async_exchange_end(exch);
     895        async_hangup(sess);
     896        return EOK;
     897}
     898
     899/** Send taskbar configuration change notification.
     900 *
     901 * @param nchan Notification channel (TBARCFG_NOTIFY_DEFAULT)
     902 */
     903errno_t tbarcfg_notify(const char *nchan)
     904{
     905        errno_t rc;
     906        category_id_t catid;
     907        service_id_t *svcs = NULL;
     908        size_t count, i;
     909
     910        rc = loc_category_get_id(nchan, &catid, 0);
     911        if (rc != EOK)
     912                return rc;
     913
     914        rc = loc_category_get_svcs(catid, &svcs, &count);
     915        if (rc != EOK)
     916                return rc;
     917
     918        for (i = 0; i < count; i++) {
     919                rc = tbarcfg_notify_svc(svcs[i]);
     920                if (rc != EOK)
     921                        goto error;
     922        }
     923
     924        free(svcs);
     925        return EOK;
     926error:
     927        free(svcs);
     928        return rc;
     929}
     930
     931/** Taskbar configuration connection handler.
     932 *
     933 * @param icall Initial call
     934 * @param arg Argument (tbarcfg_listener_t *)
     935 */
     936static void tbarcfg_notify_conn(ipc_call_t *icall, void *arg)
     937{
     938        tbarcfg_listener_t *lst = (tbarcfg_listener_t *)arg;
     939
     940        /* Accept the connection */
     941        async_accept_0(icall);
     942
     943        while (true) {
     944                ipc_call_t call;
     945                async_get_call(&call);
     946                sysarg_t method = ipc_get_imethod(&call);
     947
     948                if (!method) {
     949                        /* The other side has hung up */
     950                        async_answer_0(&call, EOK);
     951                        return;
     952                }
     953
     954                switch (method) {
     955                case TBARCFG_NOTIFY_NOTIFY:
     956                        lst->cb(lst->arg);
     957                        async_answer_0(&call, EOK);
     958                        break;
     959                default:
     960                        async_answer_0(&call, EINVAL);
     961                }
     962        }
     963}
     964
    786965/** @}
    787966 */
  • uspace/lib/tbarcfg/test/tbarcfg.c

    r90ba06c ree3b28a9  
    3030#include <pcut/pcut.h>
    3131#include <tbarcfg/tbarcfg.h>
     32#include <stdbool.h>
    3233#include <stdio.h>
    3334
     
    3536
    3637PCUT_TEST_SUITE(tbarcfg);
     38
     39typedef struct {
     40        bool notified;
     41} tbarcfg_test_resp_t;
     42
     43static void test_cb(void *);
    3744
    3845/** Creating, opening and closing taskbar configuration */
     
    554561}
    555562
     563/** Notifications can be delivered from tbarcfg_notify() to a listener. */
     564PCUT_TEST(notify)
     565{
     566        errno_t rc;
     567        tbarcfg_listener_t *lst;
     568        tbarcfg_test_resp_t test_resp;
     569
     570        test_resp.notified = false;
     571
     572        printf("create listener resp=%p\n", (void *)&test_resp);
     573        rc = tbarcfg_listener_create(TBARCFG_NOTIFY_DEFAULT,
     574            test_cb, &test_resp, &lst);
     575        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     576
     577        rc = tbarcfg_notify(TBARCFG_NOTIFY_DEFAULT);
     578        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     579
     580        PCUT_ASSERT_TRUE(test_resp.notified);
     581        tbarcfg_listener_destroy(lst);
     582}
     583
     584static void test_cb(void *arg)
     585{
     586        tbarcfg_test_resp_t *resp = (tbarcfg_test_resp_t *)arg;
     587
     588        printf("test_cb: executing resp=%p\n", (void *)resp);
     589        resp->notified = true;
     590}
     591
    556592PCUT_EXPORT(tbarcfg);
  • uspace/lib/ui/src/menuentry.c

    r90ba06c ree3b28a9  
    11/*
    2  * Copyright (c) 2023 Jiri Svoboda
     2 * Copyright (c) 2024 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    145145                return;
    146146
     147        mentry->menu->total_h -= ui_menu_entry_height(mentry);
     148        /* NOTE: max_caption_w/max_shortcut_w not updated (speed) */
     149
    147150        list_remove(&mentry->lentries);
     151
     152        /*
     153         * If we emptied the menu, reset accumulated dims so they
     154         * can be correctly calculated when (if) the menu is
     155         * re-populated.
     156         */
     157        if (list_empty(&mentry->menu->entries)) {
     158                mentry->menu->total_h = 0;
     159                mentry->menu->max_caption_w = 0;
     160                mentry->menu->max_shortcut_w = 0;
     161        }
     162
    148163        free(mentry->caption);
    149164        free(mentry);
  • uspace/srv/locsrv/locsrv.c

    r90ba06c ree3b28a9  
    11/*
     2 * Copyright (c) 2024 Jiri Svoboda
    23 * Copyright (c) 2007 Josef Cejka
    3  * Copyright (c) 2011 Jiri Svoboda
    44 * All rights reserved.
    55 *
     
    13541354        categ_dir_add_cat(&cdir, cat);
    13551355
     1356        cat = category_new("tbarcfg-notif");
     1357        categ_dir_add_cat(&cdir, cat);
     1358
    13561359        cat = category_new("test3");
    13571360        categ_dir_add_cat(&cdir, cat);
Note: See TracChangeset for help on using the changeset viewer.