Esempio n. 1
0
void menu_clear_entries(ObMenu *self)
{
#ifdef DEBUG
    /* assert that the menu isn't visible */
    {
        GList *it;
        ObMenuFrame *f;

        for (it = menu_frame_visible; it; it = g_list_next(it)) {
            f = it->data;
            g_assert(f->menu != self);
        }
    }
#endif

    while (self->entries) {
        menu_entry_unref(self->entries->data);
        self->entries = g_list_delete_link(self->entries, self->entries);
    }
    self->more_menu->entries = self->entries; /* keep it in sync */
}
Esempio n. 2
0
static void menu_entry_frame_free(ObMenuEntryFrame *self)
{
    if (self) {
        window_remove(self->window);

        XDestroyWindow(obt_display, self->text);
        XDestroyWindow(obt_display, self->window);
        g_hash_table_remove(menu_frame_map, &self->text);
        g_hash_table_remove(menu_frame_map, &self->window);
        if ((self->entry->type == OB_MENU_ENTRY_TYPE_NORMAL) ||
            (self->entry->type == OB_MENU_ENTRY_TYPE_SUBMENU)) {
            XDestroyWindow(obt_display, self->icon);
            g_hash_table_remove(menu_frame_map, &self->icon);
        }
        if (self->entry->type == OB_MENU_ENTRY_TYPE_SUBMENU) {
            XDestroyWindow(obt_display, self->bullet);
            g_hash_table_remove(menu_frame_map, &self->bullet);
        }

        menu_entry_unref(self->entry);
        g_slice_free(ObMenuEntryFrame, self);
    }
}
Esempio n. 3
0
static void menu_frame_update(ObMenuFrame *self)
{
    GList *mit, *fit;
    const Rect *a;
    gint h;

    menu_pipe_execute(self->menu);
    menu_find_submenus(self->menu);

    self->selected = NULL;

    /* start at show_from */
    mit = g_list_nth(self->menu->entries, self->show_from);

    /* go through the menu's and frame's entries and connect the frame entries
       to the menu entries */
    for (fit = self->entries; mit && fit;
         mit = g_list_next(mit), fit = g_list_next(fit))
    {
        ObMenuEntryFrame *f = fit->data;
        f->entry = mit->data;
    }

    /* if there are more menu entries than in the frame, add them */
    while (mit) {
        ObMenuEntryFrame *e = menu_entry_frame_new(mit->data, self);
        self->entries = g_list_append(self->entries, e);
        mit = g_list_next(mit);
    }

    /* if there are more frame entries than menu entries then get rid of
       them */
    while (fit) {
        GList *n = g_list_next(fit);
        menu_entry_frame_free(fit->data);
        self->entries = g_list_delete_link(self->entries, fit);
        fit = n;
    }

    /* * make the menu fit on the screen */

    /* calculate the height of the menu */
    h = 0;
    for (fit = self->entries; fit; fit = g_list_next(fit))
        h += menu_entry_frame_get_height(fit->data,
                                         fit == self->entries,
                                         g_list_next(fit) == NULL);
    /* add the border at the top and bottom */
    h += ob_rr_theme->mbwidth * 2;

    a = screen_physical_area_monitor(self->monitor);

    if (h > a->height) {
        GList *flast, *tmp;
        gboolean last_entry = TRUE;

        /* take the height of our More... entry into account */
        h += menu_entry_frame_get_height(NULL, FALSE, TRUE);

        /* start at the end of the entries */
        flast = g_list_last(self->entries);

        /* pull out all the entries from the frame that don't
           fit on the screen, leaving at least 1 though */
        while (h > a->height && g_list_previous(flast) != NULL) {
            /* update the height, without this entry */
            h -= menu_entry_frame_get_height(flast->data, FALSE, last_entry);

            /* destroy the entry we're not displaying */
            tmp = flast;
            flast = g_list_previous(flast);
            menu_entry_frame_free(tmp->data);
            self->entries = g_list_delete_link(self->entries, tmp);

            /* only the first one that we see is the last entry in the menu */
            last_entry = FALSE;
        };

        {
            ObMenuEntry *more_entry;
            ObMenuEntryFrame *more_frame;
            /* make the More... menu entry frame which will display in this
               frame.
               if self->menu->more_menu is NULL that means that this is already
               More... menu, so just use ourself.
            */
            more_entry = menu_get_more((self->menu->more_menu ?
                                        self->menu->more_menu :
                                        self->menu),
                                       /* continue where we left off */
                                       self->show_from +
                                       g_list_length(self->entries));
            more_frame = menu_entry_frame_new(more_entry, self);
            /* make it get deleted when the menu frame goes away */
            menu_entry_unref(more_entry);

            /* add our More... entry to the frame */
            self->entries = g_list_append(self->entries, more_frame);
        }
    }

    menu_frame_render(self);
}
Esempio n. 4
0
void menu_entry_remove(ObMenuEntry *self)
{
    self->menu->entries = g_list_remove(self->menu->entries, self);
    menu_entry_unref(self);
}