/* -*- 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) 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 "config.h"
#include "render/theme.h"
#define PADDING 2
#define MAX_MENU_WIDTH 400
#define FRAME_EVENTMASK (ButtonPressMask |ButtonMotionMask | EnterWindowMask |\
- LeaveWindowMask)
+ LeaveWindowMask)
#define TITLE_EVENTMASK (ButtonPressMask | ButtonMotionMask)
#define ENTRY_EVENTMASK (EnterWindowMask | LeaveWindowMask | \
ButtonPressMask | ButtonReleaseMask)
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, unsigned long mask,
- XSetWindowAttributes *attrib)
+static Window createWindow(Window parent, gulong mask,
+ XSetWindowAttributes *attrib)
{
return XCreateWindow(ob_display, parent, 0, 0, 1, 1, 0,
- RrDepth(ob_rr_inst), InputOutput,
+ RrDepth(ob_rr_inst), InputOutput,
RrVisual(ob_rr_inst), mask, attrib);
}
gint dx = 0, dy = 0;
gint pos, half;
- for (i = 0; i < screen_num_monitors; ++i) {
- a = screen_physical_area_monitor(i);
- if (RECT_INTERSECTS_RECT(*a, self->area))
- break;
- }
- if (!a) a = screen_physical_area_monitor(0);
+ a = screen_physical_area_monitor(self->monitor);
half = g_list_length(self->entries) / 2;
pos = g_list_index(self->entries, self->selected);
if (dx || dy) {
ObMenuFrame *f;
- for (f = self; f; f = f->parent)
+ /* move the current menu frame to fit, but dont touch parents yet */
+ menu_frame_move(self, self->area.x + dx, self->area.y + dy);
+ if (!config_menu_xorstyle)
+ dy = 0; /* if we want to be like xor, move parents in y- *
+ * and x-direction, otherwise just in x-dir */
+ for (f = self->parent; f; f = f->parent)
menu_frame_move(f, f->area.x + dx, f->area.y + dy);
for (f = self->child; f; f = f->child)
menu_frame_move(f, f->area.x + dx, f->area.y + dy);
- XWarpPointer(ob_display, None, None, 0, 0, 0, 0, dx, dy);
+ if (config_menu_warppointer)
+ XWarpPointer(ob_display, None, None, 0, 0, 0, 0, dx, dy);
}
}
menu_frame_render(self);
}
-void menu_frame_show(ObMenuFrame *self, ObMenuFrame *parent)
+gboolean menu_frame_show(ObMenuFrame *self, ObMenuFrame *parent)
{
GList *it;
if (g_list_find(menu_frame_visible, self))
- return;
+ return TRUE;
if (menu_frame_visible == NULL) {
/* no menus shown yet */
if (!grab_pointer(TRUE, OB_CURSOR_NONE))
- return;
+ return FALSE;
if (!grab_keyboard(TRUE)) {
grab_pointer(FALSE, OB_CURSOR_NONE);
- return;
+ return FALSE;
}
}
if (parent) {
+ self->monitor = parent->monitor;
if (parent->child)
menu_frame_hide(parent->child);
parent->child = self;
menu_frame_move_on_screen(self);
XMapWindow(ob_display, self->window);
+
+ return TRUE;
}
void menu_frame_hide(ObMenuFrame *self)
void menu_frame_hide_all()
{
+ if (config_submenu_show_delay) {
+ /* remove any submenu open requests */
+ ob_main_loop_timeout_remove(ob_main_loop,
+ menu_entry_frame_submenu_timeout);
+ }
GList *it = g_list_last(menu_frame_visible);
if (it)
menu_frame_hide(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);
+ }
+ }
}
}