]> Dogcows Code - chaz/openbox/blobdiff - openbox/menuframe.c
make menus also saveunder
[chaz/openbox] / openbox / menuframe.c
index 03e6162104f05889dd6f550701295ad98850e516..99b7dceebc0436c21e7f3c6155316b841bf303dd 100644 (file)
@@ -1,6 +1,7 @@
 /* -*- 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
@@ -22,6 +23,7 @@
 #include "screen.h"
 #include "grab.h"
 #include "openbox.h"
+#include "config.h"
 #include "render/theme.h"
 
 #define PADDING 2
@@ -29,7 +31,7 @@
 #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)
@@ -41,12 +43,13 @@ static ObMenuEntryFrame* menu_entry_frame_new(ObMenuEntry *entry,
 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)
+                           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);
 }
 
@@ -63,8 +66,9 @@ ObMenuFrame* menu_frame_new(ObMenu *menu, ObClient *client)
     self->client = client;
 
     attr.event_mask = FRAME_EVENTMASK;
+    attr.save_under = True;
     self->window = createWindow(RootWindow(ob_display, ob_screen),
-                                   CWEventMask, &attr);
+                                   CWEventMask | CWSaveUnder, &attr);
     attr.event_mask = TITLE_EVENTMASK;
     self->title = createWindow(self->window, CWEventMask, &attr);
     self->items = createWindow(self->window, 0, NULL);
@@ -189,12 +193,7 @@ void menu_frame_move_on_screen(ObMenuFrame *self)
     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);
@@ -217,11 +216,17 @@ void menu_frame_move_on_screen(ObMenuFrame *self)
     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);
     }
 }
 
@@ -602,6 +607,7 @@ gboolean menu_frame_show(ObMenuFrame *self, ObMenuFrame *parent)
     }
 
     if (parent) {
+        self->monitor = parent->monitor;
         if (parent->child)
             menu_frame_hide(parent->child);
         parent->child = self;
@@ -659,6 +665,11 @@ 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);
@@ -713,6 +724,12 @@ ObMenuEntryFrame* menu_entry_frame_under(gint x, gint y)
     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;
@@ -722,6 +739,12 @@ void menu_frame_select(ObMenuFrame *self, ObMenuEntryFrame *entry)
         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;
 
@@ -733,8 +756,18 @@ void menu_frame_select(ObMenuFrame *self, ObMenuEntryFrame *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);
+            }
+        }
     }
 }
 
This page took 0.024068 seconds and 4 git commands to generate.