/* -*- indent-tabs-mode: nil; tab-width: 4; c-basic-offset: 4; -*-
menuframe.c for the Openbox window manager
- Copyright (c) 2004 Mikael Magnusson
+ Copyright (c) 2006 Mikael Magnusson
Copyright (c) 2003 Ben Jansens
This program is free software; you can redistribute it and/or modify
#include "screen.h"
#include "grab.h"
#include "openbox.h"
+#include "mainloop.h"
#include "config.h"
#include "render/theme.h"
static void menu_entry_frame_free(ObMenuEntryFrame *self);
static void menu_frame_render(ObMenuFrame *self);
static void menu_frame_update(ObMenuFrame *self);
+static gboolean menu_entry_frame_submenu_timeout(gpointer data);
static Window createWindow(Window parent, gulong mask,
XSetWindowAttributes *attrib)
attr.event_mask = FRAME_EVENTMASK;
self->window = createWindow(RootWindow(ob_display, ob_screen),
- CWEventMask, &attr);
+ CWEventMask, &attr);
attr.event_mask = TITLE_EVENTMASK;
self->title = createWindow(self->window, CWEventMask, &attr);
self->items = createWindow(self->window, 0, NULL);
void menu_frame_move_on_screen(ObMenuFrame *self)
{
Rect *a = NULL;
- guint i;
gint dx = 0, dy = 0;
gint pos, half;
case OB_MENU_ENTRY_TYPE_SEPARATOR:
th = SEPARATOR_HEIGHT + 2*PADDING;
break;
+ default:
+ g_assert_not_reached();
}
RECT_SET_SIZE(self->area, self->frame->inner_w, th);
XResizeWindow(ob_display, self->window,
gboolean has_icon = FALSE;
ObMenu *sub;
- XSetWindowBorderWidth(ob_display, self->window, ob_rr_theme->bwidth);
+ XSetWindowBorderWidth(ob_display, self->window, ob_rr_theme->mbwidth);
XSetWindowBorder(ob_display, self->window,
- RrColorPixel(ob_rr_theme->b_color));
+ RrColorPixel(ob_rr_theme->menu_b_color));
if (!self->parent && self->show_title) {
XMoveWindow(ob_display, self->title,
- -ob_rr_theme->bwidth, h - ob_rr_theme->bwidth);
+ -ob_rr_theme->mbwidth, h - ob_rr_theme->mbwidth);
self->a_title->texture[0].data.text.string = self->menu->title;
RrMinsize(self->a_title, &tw, &th);
- tw = MIN(tw, MAX_MENU_WIDTH) + ob_rr_theme->padding * 2;
+ tw = MIN(tw, MAX_MENU_WIDTH) + ob_rr_theme->paddingx * 2;
w = MAX(w, tw);
th = ob_rr_theme->menu_title_height;
- h += (self->title_h = th + ob_rr_theme->bwidth);
+ h += (self->title_h = th + ob_rr_theme->mbwidth);
- XSetWindowBorderWidth(ob_display, self->title, ob_rr_theme->bwidth);
+ XSetWindowBorderWidth(ob_display, self->title, ob_rr_theme->mbwidth);
XSetWindowBorder(ob_display, self->title,
- RrColorPixel(ob_rr_theme->b_color));
+ RrColorPixel(ob_rr_theme->menu_b_color));
}
XMoveWindow(ob_display, self->items, 0, h);
if (!self->parent && self->show_title) {
XResizeWindow(ob_display, self->title,
- w, self->title_h - ob_rr_theme->bwidth);
+ w, self->title_h - ob_rr_theme->mbwidth);
RrPaint(self->a_title, self->title,
- w, self->title_h - ob_rr_theme->bwidth);
+ w, self->title_h - ob_rr_theme->mbwidth);
XMapWindow(ob_display, self->title);
} else
XUnmapWindow(ob_display, self->title);
for (it = self->entries; it; it = g_list_next(it))
menu_entry_frame_render(it->data);
- w += ob_rr_theme->bwidth * 2;
- h += ob_rr_theme->bwidth * 2;
+ w += ob_rr_theme->mbwidth * 2;
+ h += ob_rr_theme->mbwidth * 2;
RECT_SET_SIZE(self->area, w, h);
}
if (parent) {
+ self->monitor = parent->monitor;
if (parent->child)
menu_frame_hide(parent->child);
parent->child = self;
menu_frame_update(self);
menu_frame_visible = g_list_prepend(menu_frame_visible, self);
+
+ if (config_menu_middle) {
+ if (self->parent)
+ menu_frame_move(self, self->area.x, self->area.y
+ - self->area.height/2
+ + self->item_h/2);
+ else if (self->show_title)
+ menu_frame_move(self, self->area.x - self->area.width/2,
+ self->area.y - self->title_h*3/4);
+ }
menu_frame_move_on_screen(self);
void menu_frame_hide_all()
{
- GList *it = g_list_last(menu_frame_visible);
- if (it)
+ GList *it;
+
+ if (config_submenu_show_delay) {
+ /* remove any submenu open requests */
+ ob_main_loop_timeout_remove(ob_main_loop,
+ menu_entry_frame_submenu_timeout);
+ }
+ if ((it = g_list_last(menu_frame_visible)))
menu_frame_hide(it->data);
}
GList *it;
if ((frame = menu_frame_under(x, y))) {
- x -= ob_rr_theme->bwidth + frame->area.x;
- y -= frame->title_h + ob_rr_theme->bwidth + frame->area.y;
+ x -= ob_rr_theme->mbwidth + frame->area.x;
+ y -= frame->title_h + ob_rr_theme->mbwidth + frame->area.y;
for (it = frame->entries; it; it = g_list_next(it)) {
ObMenuEntryFrame *e = it->data;
return ret;
}
+static gboolean menu_entry_frame_submenu_timeout(gpointer data)
+{
+ menu_entry_frame_show_submenu((ObMenuEntryFrame*)data);
+ return FALSE;
+}
+
void menu_frame_select(ObMenuFrame *self, ObMenuEntryFrame *entry)
{
ObMenuEntryFrame *old = self->selected;
entry = old;
if (old == entry) return;
+
+ if (config_submenu_show_delay) {
+ /* remove any submenu open requests */
+ ob_main_loop_timeout_remove(ob_main_loop,
+ menu_entry_frame_submenu_timeout);
+ }
self->selected = entry;
if (self->selected) {
menu_entry_frame_render(self->selected);
- if (self->selected->entry->type == OB_MENU_ENTRY_TYPE_SUBMENU)
- menu_entry_frame_show_submenu(self->selected);
+ if (self->selected->entry->type == OB_MENU_ENTRY_TYPE_SUBMENU) {
+ if (config_submenu_show_delay) {
+ /* initiate a new submenu open request */
+ ob_main_loop_timeout_add(ob_main_loop,
+ config_submenu_show_delay * 1000,
+ menu_entry_frame_submenu_timeout,
+ self->selected,
+ NULL);
+ } else {
+ menu_entry_frame_show_submenu(self->selected);
+ }
+ }
}
}
f = menu_frame_new(self->entry->data.submenu.submenu,
self->frame->client);
menu_frame_move(f,
- self->frame->area.x + self->frame->area.width
- - ob_rr_theme->menu_overlap - ob_rr_theme->bwidth,
- self->frame->area.y + self->frame->title_h +
- self->area.y + ob_rr_theme->menu_overlap);
+ self->frame->area.x
+ + self->frame->area.width
+ - ob_rr_theme->menu_overlap
+ - ob_rr_theme->mbwidth,
+ self->frame->area.y
+ + self->frame->title_h
+ + self->area.y
+ + (config_menu_middle ? 1 : ob_rr_theme->menu_overlap));
menu_frame_show(f, self->frame);
}