Fri Oct 8 15:31:49 PDT 1999 Michael Jennings <mej@eterm.org>

This should fix all the weird menu behavior from time to time (well,
	I hope it does anyway).


SVN revision: 719
This commit is contained in:
Michael Jennings 1999-10-08 18:49:57 +00:00
parent dd84c6abab
commit 11b7b87dad
6 changed files with 110 additions and 102 deletions

View File

@ -2556,3 +2556,9 @@ Thu Oct 7 18:48:31 PDT 1999 Michael Jennings <mej@eterm.org>
fixing some small leaks here and there.
-------------------------------------------------------------------------------
Fri Oct 8 15:31:49 PDT 1999 Michael Jennings <mej@eterm.org>
This should fix all the weird menu behavior from time to time (well,
I hope it does anyway).
-------------------------------------------------------------------------------

View File

@ -2158,7 +2158,7 @@ run_command(char *argv[])
int i;
for (i = 0; argv[i]; i++) {
DPRINTF1(("argv[%d] = \"%s\"\n", i, argv[i]));
DPRINTF(("argv[%d] = \"%s\"\n", i, argv[i]));
}
}
#endif

View File

@ -54,7 +54,7 @@ extern unsigned int debug_level;
/* Macros for printing debugging messages */
# if DEBUG >= 1
# ifndef DPRINTF
# define DPRINTF(x) do { if (debug_level >= 1) {__DEBUG(); real_dprintf x;} } while (0)
# define DPRINTF(x) do { __DEBUG(); real_dprintf x; } while (0)
# endif
# define DPRINTF1(x) do { if (debug_level >= 1) {__DEBUG(); real_dprintf x;} } while (0)
# define DPRINTF2(x) do { if (debug_level >= 2) {__DEBUG(); real_dprintf x;} } while (0)

View File

@ -51,9 +51,13 @@ menulist_t *menu_list = NULL;
static GC topShadowGC, botShadowGC;
static Time button_press_time;
static menu_t *current_menu;
static menuitem_t *current_item;
inline void
static inline void grab_pointer(Window win);
static inline void ungrab_pointer(void);
static inline void draw_string(Drawable d, GC gc, int x, int y, char *str, size_t len);
static inline unsigned short center_coords(register unsigned short c1, register unsigned short c2);
static inline void
grab_pointer(Window win)
{
@ -84,7 +88,7 @@ grab_pointer(Window win)
}
}
inline void
static inline void
ungrab_pointer(void)
{
@ -92,7 +96,7 @@ ungrab_pointer(void)
XUngrabPointer(Xdisplay, CurrentTime);
}
inline void
static inline void
draw_string(Drawable d, GC gc, int x, int y, char *str, size_t len)
{
@ -106,7 +110,7 @@ draw_string(Drawable d, GC gc, int x, int y, char *str, size_t len)
XDrawString(Xdisplay, d, gc, x, y, str, len);
}
inline unsigned short
static inline unsigned short
center_coords(register unsigned short c1, register unsigned short c2)
{
@ -248,6 +252,7 @@ menu_handle_button_press(event_t * ev)
unsigned char
menu_handle_button_release(event_t * ev)
{
menuitem_t *item;
D_EVENTS(("menu_handle_button_release(ev [0x%08x] on window 0x%08x)\n", ev, ev->xany.window));
@ -263,13 +268,14 @@ menu_handle_button_release(event_t * ev)
if (button_press_time && (ev->xbutton.time - button_press_time > MENU_CLICK_TIME)) {
/* Take action here based on the current menu item */
if (current_item) {
if (current_item->type == MENUITEM_SUBMENU) {
menu_display_submenu(current_menu, current_item);
current_item = NULL;
} else {
menu_action(current_item);
menuitem_deselect(current_menu, current_item);
if (current_menu) {
if ((item = menuitem_get_current(current_menu)) != NULL) {
if (item->type == MENUITEM_SUBMENU) {
menu_display_submenu(current_menu, item);
} else {
menu_action(item);
menuitem_deselect(current_menu);
}
}
}
}
@ -283,14 +289,15 @@ menu_handle_button_release(event_t * ev)
D_MENU(("Single click mode, detected click.\n"));
if ((ev->xbutton.x >= 0) && (ev->xbutton.y >= 0) && (ev->xbutton.x < current_menu->w) && (ev->xbutton.y < current_menu->h)) {
/* Click inside the menu window. Activate the current item. */
if (current_item) {
if (current_item->type == MENUITEM_SUBMENU) {
menu_display_submenu(current_menu, current_item);
current_item = NULL;
} else {
menu_action(current_item);
menuitem_deselect(current_menu, current_item);
menu_reset_all(menu_list);
if (current_menu) {
if ((item = menuitem_get_current(current_menu)) != NULL) {
if (item->type == MENUITEM_SUBMENU) {
menu_display_submenu(current_menu, item);
} else {
menu_action(item);
menuitem_deselect(current_menu);
menu_reset_all(menu_list);
}
}
}
} else {
@ -319,19 +326,6 @@ menu_handle_motion_notify(event_t * ev)
if (!current_menu) {
return 1;
}
#if 0
if ((current_menu->win != ev->xany.window)
&& !(current_item && current_item->type == MENUITEM_SUBMENU
&& current_item->action.submenu && current_item->action.submenu->win == ev->xany.window)) {
register menu_t *menu;
menu = find_menu_by_window(menu_list, ev->xany.window);
if (menu) {
menu_reset_tree(current_menu);
current_menu = menu;
}
}
#endif
if (button_press_time) {
current_menu->state |= MENU_STATE_IS_DRAGGING;
@ -348,22 +342,22 @@ menu_handle_motion_notify(event_t * ev)
XTranslateCoordinates(Xdisplay, ev->xany.window, Xroot, ev->xbutton.x, ev->xbutton.y, &dest_x, &dest_y, &child);
menu = find_menu_by_window(menu_list, child);
if (menu) {
if (menu && menu != current_menu) {
D_MENU(("Mouse is actually over window 0x%08x belonging to menu \"%s\"\n", child, menu->title));
ungrab_pointer();
grab_pointer(menu->win);
current_menu->state &= ~(MENU_STATE_IS_FOCUSED);
menu->state |= MENU_STATE_IS_FOCUSED;
if (!menu_is_child(current_menu, menu)) {
menu_reset_tree(current_menu);
}
current_menu = menu;
XTranslateCoordinates(Xdisplay, ev->xany.window, child, ev->xbutton.x, ev->xbutton.y, &dest_x, &dest_y, &child);
item = find_item_by_coords(menu, dest_x, dest_y);
if (item && item != current_item) {
ungrab_pointer();
grab_pointer(menu->win);
current_menu->state &= ~(MENU_STATE_IS_FOCUSED);
menu->state |= MENU_STATE_IS_FOCUSED;
if (!menu_is_child(current_menu, menu)) {
menu_reset_tree(current_menu);
}
current_menu = menu;
menu_reset_submenus(menu);
menuitem_change_current(item);
if (!item || item != menuitem_get_current(current_menu)) {
menu_reset_submenus(current_menu);
}
menuitem_change_current(item);
}
}
@ -435,6 +429,7 @@ menu_create(char *title)
CWOverrideRedirect | CWSaveUnder | CWBackingStore | CWBorderPixel | CWColormap, &xattr);
menu->gc = XCreateGC(Xdisplay, menu->win, GCForeground, &gcvalue);
menuitem_clear_current(menu);
return menu;
}
@ -552,7 +547,6 @@ find_item_by_coords(menu_t * menu, int x, int y)
for (i = 0; i < menu->numitems; i++) {
item = menu->items[i];
if ((x > item->x) && (y > item->y) && (x < item->x + item->w) && (y < item->y + item->h) && (item->type != MENUITEM_SEP)) {
menu->curitem = i;
return (item);
}
}
@ -577,35 +571,41 @@ find_item_in_menu(menu_t * menu, menuitem_t * item)
}
void
menuitem_change_current(menuitem_t * item)
menuitem_change_current(menuitem_t *item)
{
menuitem_t *current;
D_MENU(("menuitem_change_current(): Changing current_item from \"%s\" to \"%s\"\n", (current_item ? current_item->text : "(NULL)"),
(item ? item->text : "(NULL)")));
ASSERT(current_menu != NULL);
if (current_item != item) {
if (current_item) {
current = menuitem_get_current(current_menu);
if (current != item) {
D_MENU(("menuitem_change_current(): Changing current item in menu \"%s\" from \"%s\" to \"%s\"\n", current_menu->title, (current ? current->text : "(NULL)"), (item ? item->text : "(NULL)")));
if (current) {
/* Reset the current item */
menuitem_deselect(current_menu, current_item);
menuitem_deselect(current_menu);
/* If we're changing from one submenu to another and neither is a child of the other, or if we're changing from a submenu to
no current item at all, reset the tree for the current submenu */
if (current_item->type == MENUITEM_SUBMENU && current_item->action.submenu != NULL) {
if (current->type == MENUITEM_SUBMENU && current->action.submenu != NULL) {
if ((item && item->type == MENUITEM_SUBMENU && item->action.submenu != NULL
&& !menu_is_child(current_item->action.submenu, item->action.submenu)
&& !menu_is_child(item->action.submenu, current_item->action.submenu))
&& !menu_is_child(current->action.submenu, item->action.submenu)
&& !menu_is_child(item->action.submenu, current->action.submenu))
|| (!item)) {
menu_reset_tree(current_item->action.submenu);
menu_reset_tree(current->action.submenu);
}
}
}
current_item = item;
if (current_item) {
menuitem_select(current_menu, current_item);
if (current_item->type == MENUITEM_SUBMENU) {
if (item) {
menuitem_set_current(current_menu, find_item_in_menu(current_menu, item));
menuitem_select(current_menu);
if (item->type == MENUITEM_SUBMENU) {
/* Display the submenu */
menu_display_submenu(current_menu, current_item);
menu_display_submenu(current_menu, item);
}
} else {
menuitem_clear_current(current_menu);
}
} else {
D_MENU(("menuitem_change_current(): Current item in menu \"%s\" does not require changing.\n", current_menu->title));
}
}
@ -678,12 +678,13 @@ menu_reset(menu_t * menu)
ASSERT(menu != NULL);
D_MENU(("menu_reset() called for menu \"%s\" (window 0x%08x)\n", menu->title, menu->win));
menu->state &= ~(MENU_STATE_IS_CURRENT | MENU_STATE_IS_DRAGGING);
XUnmapWindow(Xdisplay, menu->swin);
if (menu->state & MENU_STATE_IS_MAPPED) {
XUnmapWindow(Xdisplay, menu->win);
menu->state &= ~(MENU_STATE_IS_MAPPED);
if (!(menu->state & MENU_STATE_IS_MAPPED)) {
return;
}
menu->state &= ~(MENU_STATE_IS_CURRENT | MENU_STATE_IS_DRAGGING | MENU_STATE_IS_MAPPED);
XUnmapWindow(Xdisplay, menu->swin);
XUnmapWindow(Xdisplay, menu->win);
menuitem_clear_current(menu);
}
void
@ -691,7 +692,6 @@ menu_reset_all(menulist_t * list)
{
register unsigned short i;
register menu_t *menu;
ASSERT(list != NULL);
@ -699,18 +699,11 @@ menu_reset_all(menulist_t * list)
return;
D_MENU(("menu_reset_all() called\n"));
if (current_item != NULL) {
menuitem_deselect(current_menu, current_item);
current_item = NULL;
if (menuitem_get_current(current_menu) != NULL) {
menuitem_deselect(current_menu);
}
for (i = 0; i < list->nummenus; i++) {
menu = list->menus[i];
menu->state &= ~(MENU_STATE_IS_CURRENT | MENU_STATE_IS_DRAGGING);
XUnmapWindow(Xdisplay, menu->swin);
if (menu->state & MENU_STATE_IS_MAPPED) {
XUnmapWindow(Xdisplay, menu->win);
menu->state &= ~(MENU_STATE_IS_MAPPED);
}
menu_reset(list->menus[i]);
}
current_menu = NULL;
}
@ -725,18 +718,16 @@ menu_reset_tree(menu_t * menu)
ASSERT(menu != NULL);
D_MENU(("menu_reset_tree() called for menu \"%s\" (window 0x%08x)\n", menu->title, menu->win));
if (!(menu->state & MENU_STATE_IS_MAPPED)) {
return;
}
for (i = 0; i < menu->numitems; i++) {
item = menu->items[i];
if (item->type == MENUITEM_SUBMENU && item->action.submenu != NULL) {
menu_reset_tree(item->action.submenu);
}
}
menu->state &= ~(MENU_STATE_IS_CURRENT | MENU_STATE_IS_DRAGGING);
XUnmapWindow(Xdisplay, menu->swin);
if (menu->state & MENU_STATE_IS_MAPPED) {
XUnmapWindow(Xdisplay, menu->win);
menu->state &= ~(MENU_STATE_IS_MAPPED);
}
menu_reset(menu);
}
void
@ -758,12 +749,14 @@ menu_reset_submenus(menu_t * menu)
}
void
menuitem_select(menu_t * menu, menuitem_t * item)
menuitem_select(menu_t * menu)
{
menuitem_t *item;
ASSERT(menu != NULL);
ASSERT(item != NULL);
item = menuitem_get_current(menu);
REQUIRE(item != NULL);
D_MENU(("menuitem_select(): Selecting new current item \"%s\" within menu \"%s\" (window 0x%08x, selection window 0x%08x)\n",
item->text, menu->title, menu->win, menu->swin));
item->state |= MENU_STATE_IS_CURRENT;
@ -784,24 +777,24 @@ menuitem_select(menu_t * menu, menuitem_t * item)
}
void
menuitem_deselect(menu_t * menu, menuitem_t * item)
menuitem_deselect(menu_t * menu)
{
menuitem_t *item;
ASSERT(menu != NULL);
ASSERT(item != NULL);
item = menuitem_get_current(menu);
REQUIRE(item != NULL);
D_MENU(("menuitem_deselect(): Deselecting item \"%s\"\n", item->text));
item->state &= ~(MENU_STATE_IS_CURRENT);
XUnmapWindow(Xdisplay, menu->swin);
if (find_item_in_menu(menu, item) != (unsigned short) -1) {
if (item->type == MENUITEM_SUBMENU) {
paste_simage(images[image_submenu].norm, image_submenu, menu->win, item->x, item->y, item->w - MENU_VGAP, item->h);
}
draw_string(menu->win, menu->gc, 2 * MENU_HGAP, item->y + item->h - MENU_VGAP, item->text, item->len);
if (item->rtext) {
draw_string(menu->win, menu->gc, item->x + item->w - XTextWidth(menu->font, item->rtext, item->rlen) - 2 * MENU_HGAP, item->y + item->h - MENU_VGAP,
item->rtext, item->rlen);
}
if (item->type == MENUITEM_SUBMENU) {
paste_simage(images[image_submenu].norm, image_submenu, menu->win, item->x, item->y, item->w - MENU_VGAP, item->h);
}
draw_string(menu->win, menu->gc, 2 * MENU_HGAP, item->y + item->h - MENU_VGAP, item->text, item->len);
if (item->rtext) {
draw_string(menu->win, menu->gc, item->x + item->w - XTextWidth(menu->font, item->rtext, item->rlen) - 2 * MENU_HGAP, item->y + item->h - MENU_VGAP,
item->rtext, item->rlen);
}
}

View File

@ -46,9 +46,13 @@
#define MENU_HGAP 4
#define MENU_VGAP 4
#define MENU_CLICK_TIME 20
#define NO_CURRENT_ITEM ((unsigned short) -1)
#define menu_is_pixmapped() ((images[image_menu].current->iml->im) && (images[image_menu].mode & MODE_MASK))
#define menu_submenu_is_pixmapped() ((images[image_submenu].current->iml->im) && (images[image_submenu].mode & MODE_MASK))
#define menu_is_pixmapped() ((images[image_menu].current->iml->im) && (images[image_menu].mode & MODE_MASK))
#define menu_submenu_is_pixmapped() ((images[image_submenu].current->iml->im) && (images[image_submenu].mode & MODE_MASK))
#define menuitem_get_current(m) (((m)->curitem != NO_CURRENT_ITEM) ? ((m)->items[(m)->curitem]) : (NULL))
#define menuitem_set_current(m, i) ((m)->curitem = (i))
#define menuitem_clear_current(m) ((m)->curitem = NO_CURRENT_ITEM)
/************ Structures ************/
typedef struct menu_t_struct menu_t;
@ -121,8 +125,8 @@ extern void menu_reset(menu_t *);
extern void menu_reset_all(menulist_t *);
extern void menu_reset_tree(menu_t *);
extern void menu_reset_submenus(menu_t *);
extern void menuitem_select(menu_t *, menuitem_t *);
extern void menuitem_deselect(menu_t *, menuitem_t *);
extern void menuitem_select(menu_t *);
extern void menuitem_deselect(menu_t *);
extern void menu_display_submenu(menu_t *, menuitem_t *);
extern void menu_draw(menu_t *);
extern void menu_display(int, int, menu_t *);

View File

@ -126,4 +126,9 @@ extern short bg_needs_update;
#endif
extern const char *display_name;
/************ Function Prototypes ************/
_XFUNCPROTOBEGIN
extern int eterm_bootstrap(int argc, char *argv[]);
_XFUNCPROTOEND
#endif