From b25b78404fde1c9fddee2a0f2c533bd173affddc Mon Sep 17 00:00:00 2001 From: Dana Jansens Date: Sun, 22 Apr 2007 04:28:43 +0000 Subject: [PATCH] merge r5765-r5772 from trunk (this was non-trivial) --- openbox/dock.c | 4 +-- openbox/event.c | 58 ++++++++++++++++++++++++------ openbox/frame.c | 1 + openbox/keyboard.c | 3 +- openbox/mainloop.c | 5 ++- openbox/mainloop.h | 1 + openbox/menuframe.c | 78 ++++++++++++++++++++++++++++++++--------- openbox/menuframe.h | 2 ++ openbox/startupnotify.c | 2 ++ render/theme.c | 27 ++++++++------ render/theme.h | 1 + 11 files changed, 140 insertions(+), 42 deletions(-) diff --git a/openbox/dock.c b/openbox/dock.c index 53c79139..70e11272 100644 --- a/openbox/dock.c +++ b/openbox/dock.c @@ -616,14 +616,14 @@ void dock_hide(gboolean hide) if (!hide) { if (dock->hidden && config_dock_hide) { ob_main_loop_timeout_add(ob_main_loop, config_dock_show_delay, - show_timeout, NULL, NULL); + show_timeout, NULL, g_direct_equal, NULL); } else if (!dock->hidden && config_dock_hide) { ob_main_loop_timeout_remove(ob_main_loop, hide_timeout); } } else { if (!dock->hidden && config_dock_hide) { ob_main_loop_timeout_add(ob_main_loop, config_dock_hide_delay, - hide_timeout, NULL, NULL); + hide_timeout, NULL, g_direct_equal, NULL); } else if (dock->hidden && config_dock_hide) { ob_main_loop_timeout_remove(ob_main_loop, show_timeout); } diff --git a/openbox/event.c b/openbox/event.c index 1f5bae13..9a1e13dc 100644 --- a/openbox/event.c +++ b/openbox/event.c @@ -64,6 +64,12 @@ typedef struct gboolean ignored; } ObEventData; +typedef struct +{ + ObClient *client; + Time time; +} ObFocusDelayData; + static void event_process(const XEvent *e, gpointer data); static void event_client_dest(ObClient *client, gpointer data); static void event_handle_root(XEvent *e); @@ -73,6 +79,8 @@ static void event_handle_dockapp(ObDockApp *app, XEvent *e); static void event_handle_client(ObClient *c, XEvent *e); static void event_handle_group(ObGroup *g, XEvent *e); +static void focus_delay_dest(gpointer data); +static gboolean focus_delay_cmp(gconstpointer d1, gconstpointer d2); static gboolean focus_delay_func(gpointer data); static void focus_delay_client_dest(ObClient *client, gpointer data); @@ -531,7 +539,7 @@ static void event_process(const XEvent *ec, gpointer data) ob_main_loop_timeout_add(ob_main_loop, config_menu_hide_delay * 1000, menu_hide_delay_func, - NULL, NULL); + NULL, g_direct_equal, NULL); if (e->type == ButtonPress || e->type == ButtonRelease || e->type == MotionNotify) @@ -616,13 +624,24 @@ void event_enter_client(ObClient *client) if (client_normal(client) && client_can_focus(client)) { if (config_focus_delay) { + ObFocusDelayData *data; + ob_main_loop_timeout_remove(ob_main_loop, focus_delay_func); + + data = g_new(ObFocusDelayData, 1); + data->client = client; + data->time = event_curtime; + ob_main_loop_timeout_add(ob_main_loop, config_focus_delay, focus_delay_func, - client, NULL); - } else - focus_delay_func(client); + data, focus_delay_cmp, focus_delay_dest); + } else { + ObFocusDelayData data; + data.client = client; + data.time = event_curtime; + focus_delay_func(&data); + } } } @@ -745,7 +764,7 @@ static void event_handle_client(ObClient *client, XEvent *e) if (config_focus_follow && config_focus_delay) ob_main_loop_timeout_remove_data(ob_main_loop, focus_delay_func, - client, TRUE); + client, FALSE); break; default: break; @@ -1281,6 +1300,11 @@ static void event_handle_menu(XEvent *ev) { menu_frame_select(e->frame, NULL); } + case MotionNotify: + if ((e = menu_entry_frame_under(ev->xmotion.x_root, + ev->xmotion.y_root))) + menu_frame_select(e->frame, e); + break; case KeyPress: if (ev->xkey.keycode == ob_keycode(OB_KEY_ESCAPE)) menu_frame_hide_all(); @@ -1316,21 +1340,35 @@ static gboolean menu_hide_delay_func(gpointer data) return FALSE; /* no repeat */ } +static void focus_delay_dest(gpointer data) +{ + g_free(data); +} + +static gboolean focus_delay_cmp(gconstpointer d1, gconstpointer d2) +{ + const ObFocusDelayData *f1 = d1, *f2 = d2; + return f1->client == f2->client; +} + static gboolean focus_delay_func(gpointer data) { - ObClient *c = data; + ObFocusDelayData *d = data; + Time old = event_curtime; - if (focus_client != c) { - if (client_focus(c) && config_focus_raise) - client_raise(c); + event_curtime = d->time; + if (focus_client != d->client) { + if (client_focus(d->client) && config_focus_raise) + client_raise(d->client); } + event_curtime = old; return FALSE; /* no repeat */ } static void focus_delay_client_dest(ObClient *client, gpointer data) { ob_main_loop_timeout_remove_data(ob_main_loop, focus_delay_func, - client, TRUE); + client, FALSE); } static void event_client_dest(ObClient *client, gpointer data) diff --git a/openbox/frame.c b/openbox/frame.c index 554e7b55..052f12df 100644 --- a/openbox/frame.c +++ b/openbox/frame.c @@ -977,6 +977,7 @@ void frame_flash_start(ObFrame *self) G_USEC_PER_SEC * 0.6, flash_timeout, self, + g_direct_equal, flash_done); g_get_current_time(&self->flash_end); g_time_val_add(&self->flash_end, G_USEC_PER_SEC * 5); diff --git a/openbox/keyboard.c b/openbox/keyboard.c index b95b0805..01b54b4c 100644 --- a/openbox/keyboard.c +++ b/openbox/keyboard.c @@ -271,7 +271,8 @@ void keyboard_event(ObClient *client, const XEvent *e) ob_main_loop_timeout_remove(ob_main_loop, chain_timeout); /* 5 second timeout for chains */ ob_main_loop_timeout_add(ob_main_loop, 5 * G_USEC_PER_SEC, - chain_timeout, NULL, NULL); + chain_timeout, NULL, + g_direct_equal, NULL); grab_keys(FALSE); curpos = p; grab_keys(TRUE); diff --git a/openbox/mainloop.c b/openbox/mainloop.c index e6914f89..62261dde 100644 --- a/openbox/mainloop.c +++ b/openbox/mainloop.c @@ -99,6 +99,7 @@ struct _ObMainLoopTimer gulong delay; GSourceFunc func; gpointer data; + GEqualFunc equal; GDestroyNotify destroy; /* The timer needs to be freed */ @@ -585,12 +586,14 @@ void ob_main_loop_timeout_add(ObMainLoop *loop, gulong microseconds, GSourceFunc handler, gpointer data, + GEqualFunc cmp, GDestroyNotify notify) { ObMainLoopTimer *t = g_new(ObMainLoopTimer, 1); t->delay = microseconds; t->func = handler; t->data = data; + t->equal = cmp; t->destroy = notify; t->del_me = FALSE; g_get_current_time(&loop->now); @@ -619,7 +622,7 @@ void ob_main_loop_timeout_remove_data(ObMainLoop *loop, GSourceFunc handler, for (it = loop->timers; it; it = g_slist_next(it)) { ObMainLoopTimer *t = it->data; - if (t->func == handler && t->data == data) { + if (t->func == handler && t->equal(t->data, data)) { t->del_me = TRUE; if (cancel_dest) t->destroy = NULL; diff --git a/openbox/mainloop.h b/openbox/mainloop.h index 9530f2a6..47591850 100644 --- a/openbox/mainloop.h +++ b/openbox/mainloop.h @@ -61,6 +61,7 @@ void ob_main_loop_timeout_add(ObMainLoop *loop, gulong microseconds, GSourceFunc handler, gpointer data, + GEqualFunc cmp, GDestroyNotify notify); void ob_main_loop_timeout_remove(ObMainLoop *loop, GSourceFunc handler); diff --git a/openbox/menuframe.c b/openbox/menuframe.c index fd7e9520..f359c985 100644 --- a/openbox/menuframe.c +++ b/openbox/menuframe.c @@ -163,6 +163,8 @@ static ObMenuEntryFrame* menu_entry_frame_new(ObMenuEntry *entry, RrAppearanceCopy(ob_rr_theme->a_menu_text_disabled); self->a_text_selected = RrAppearanceCopy(ob_rr_theme->a_menu_text_selected); + self->a_text_title = + RrAppearanceCopy(ob_rr_theme->a_menu_text_title); return self; } @@ -193,6 +195,7 @@ static void menu_entry_frame_free(ObMenuEntryFrame *self) RrAppearanceFree(self->a_text_normal); RrAppearanceFree(self->a_text_disabled); RrAppearanceFree(self->a_text_selected); + RrAppearanceFree(self->a_text_title); RrAppearanceFree(self->a_bullet_normal); RrAppearanceFree(self->a_bullet_selected); @@ -290,9 +293,7 @@ static void menu_entry_frame_render(ObMenuEntryFrame *self) case OB_MENU_ENTRY_TYPE_SEPARATOR: if (self->entry->data.separator.label) { item_a = self->frame->a_title; - item_a->texture[0].data.text.string = - self->entry->data.separator.label; - th = self->frame->title_h; + th = ob_rr_theme->menu_title_height; } else { item_a = self->a_normal; th = SEPARATOR_HEIGHT + 2*PADDING; @@ -326,7 +327,10 @@ static void menu_entry_frame_render(ObMenuEntryFrame *self) text_a->texture[0].data.text.string = sub ? sub->title : ""; break; case OB_MENU_ENTRY_TYPE_SEPARATOR: - text_a = self->a_text_normal; + if (self->entry->data.separator.label != NULL) + text_a = self->a_text_title; + else + text_a = self->a_text_normal; break; } @@ -354,7 +358,22 @@ static void menu_entry_frame_render(ObMenuEntryFrame *self) self->frame->item_h - 2*PADDING); break; case OB_MENU_ENTRY_TYPE_SEPARATOR: - if (self->entry->data.separator.label == NULL) { + if (self->entry->data.separator.label != NULL) { + /* labeled separator */ + XMoveResizeWindow(ob_display, self->text, + ob_rr_theme->paddingx, ob_rr_theme->paddingy, + self->area.width - 2*ob_rr_theme->paddingx, + ob_rr_theme->menu_title_height - + 2*ob_rr_theme->paddingy); + text_a->surface.parent = item_a; + text_a->surface.parentx = ob_rr_theme->paddingx; + text_a->surface.parenty = ob_rr_theme->paddingy; + RrPaint(text_a, self->text, + self->area.width - 2*ob_rr_theme->paddingx, + ob_rr_theme->menu_title_height - + 2*ob_rr_theme->paddingy); + } else { + /* unlabeled separaator */ XMoveResizeWindow(ob_display, self->text, PADDING, PADDING, self->area.width - 2*PADDING, SEPARATOR_HEIGHT); self->a_separator->surface.parent = item_a; @@ -463,6 +482,7 @@ static void menu_frame_render(ObMenuFrame *self) GList *it; gboolean has_icon = FALSE; ObMenu *sub; + ObMenuEntryFrame *e; XSetWindowBorderWidth(ob_display, self->window, ob_rr_theme->mbwidth); XSetWindowBorder(ob_display, self->window, @@ -482,12 +502,6 @@ static void menu_frame_render(ObMenuFrame *self) th += 2*PADDING; self->item_h = th; - self->a_title->texture[0].data.text.string = ""; - RrMinsize(self->a_title, &tw, &th); - tw += 2*PADDING; - th += 2*PADDING; - self->title_h = th; - RrMargins(e->a_normal, &l, &t, &r, &b); STRUT_SET(self->item_margin, MAX(self->item_margin.left, l), @@ -513,10 +527,28 @@ static void menu_frame_render(ObMenuFrame *self) for (it = self->entries; it; it = g_list_next(it)) { RrAppearance *text_a; - ObMenuEntryFrame *e = it->data; + e = it->data; + + /* if the first entry is a labeled separator, then make its border + overlap with the menu's outside border */ + if (it == self->entries && + e->entry->type == OB_MENU_ENTRY_TYPE_SEPARATOR && + e->entry->data.separator.label) + { + h -= ob_rr_theme->mbwidth; + } + + if (e->entry->type == OB_MENU_ENTRY_TYPE_SEPARATOR && + e->entry->data.separator.label) + { + e->border = ob_rr_theme->mbwidth; + } - RECT_SET_POINT(e->area, 0, h); - XMoveWindow(ob_display, e->window, 0, e->area.y); + RECT_SET_POINT(e->area, 0, h+e->border); + XMoveWindow(ob_display, e->window, e->area.x-e->border, e->area.y-e->border); + XSetWindowBorderWidth(ob_display, e->window, e->border); + XSetWindowBorder(ob_display, e->window, + RrColorPixel(ob_rr_theme->menu_b_color)); text_a = ((e->entry->type == OB_MENU_ENTRY_TYPE_NORMAL && !e->entry->data.normal.enabled) ? @@ -548,10 +580,12 @@ static void menu_frame_render(ObMenuFrame *self) break; case OB_MENU_ENTRY_TYPE_SEPARATOR: if (e->entry->data.separator.label != NULL) { - self->a_title->texture[0].data.text.string = + e->a_text_title->texture[0].data.text.string = e->entry->data.separator.label; - RrMinsize(self->a_title, &tw, &th); + RrMinsize(e->a_text_title, &tw, &th); tw = MIN(tw, MAX_MENU_WIDTH); + th = ob_rr_theme->menu_title_height + + (ob_rr_theme->mbwidth - PADDING) *2; } else { tw = 0; th = SEPARATOR_HEIGHT; @@ -564,6 +598,16 @@ static void menu_frame_render(ObMenuFrame *self) h += th; } + /* if the last entry is a labeled separator, then make its border + overlap with the menu's outside border */ + it = g_list_last(self->entries); + e = it ? it->data : NULL; + if (e && e->entry->type == OB_MENU_ENTRY_TYPE_SEPARATOR && + e->entry->data.separator.label) + { + h -= ob_rr_theme->mbwidth; + } + self->text_x = PADDING; self->text_w = w; @@ -874,7 +918,7 @@ void menu_frame_select(ObMenuFrame *self, ObMenuEntryFrame *entry) ob_main_loop_timeout_add(ob_main_loop, config_submenu_show_delay * 1000, menu_entry_frame_submenu_timeout, - self->selected, + self->selected, g_direct_equal, NULL); } else { menu_entry_frame_show_submenu(self->selected); diff --git a/openbox/menuframe.h b/openbox/menuframe.h index 9bc1bdc4..016700a7 100644 --- a/openbox/menuframe.h +++ b/openbox/menuframe.h @@ -80,6 +80,7 @@ struct _ObMenuEntryFrame guint ignore_enters; Rect area; + gint border; Window window; Window icon; @@ -98,6 +99,7 @@ struct _ObMenuEntryFrame RrAppearance *a_text_normal; RrAppearance *a_text_disabled; RrAppearance *a_text_selected; + RrAppearance *a_text_title; }; extern GHashTable *menu_frame_map; diff --git a/openbox/startupnotify.c b/openbox/startupnotify.c index bf1f44ac..5b5723e5 100644 --- a/openbox/startupnotify.c +++ b/openbox/startupnotify.c @@ -144,6 +144,7 @@ static void sn_event_func(SnMonitorEvent *ev, gpointer data) have a timeout */ ob_main_loop_timeout_add(ob_main_loop, 30 * G_USEC_PER_SEC, sn_wait_timeout, seq, + g_direct_equal, (GDestroyNotify)sn_startup_sequence_unref); change = TRUE; break; @@ -256,6 +257,7 @@ void sn_setup_spawn_environment(gchar *program, gchar *name, sn_launcher_context_ref(sn_launcher); ob_main_loop_timeout_add(ob_main_loop, 30 * G_USEC_PER_SEC, sn_launch_wait_timeout, sn_launcher, + g_direct_equal, (GDestroyNotify)sn_launcher_context_unref); setenv("DESKTOP_STARTUP_ID", id, TRUE); diff --git a/render/theme.c b/render/theme.c index 13a62cfd..c0344985 100644 --- a/render/theme.c +++ b/render/theme.c @@ -80,7 +80,8 @@ RrTheme* RrThemeNew(const RrInstance *inst, gchar *name, theme->a_focused_handle = RrAppearanceNew(inst, 0); theme->a_unfocused_handle = RrAppearanceNew(inst, 0); theme->a_menu = RrAppearanceNew(inst, 0); - theme->a_menu_title = RrAppearanceNew(inst, 1); + theme->a_menu_title = RrAppearanceNew(inst, 0); + theme->a_menu_text_title = RrAppearanceNew(inst, 1); theme->a_menu_normal = RrAppearanceNew(inst, 0); theme->a_menu_disabled = RrAppearanceNew(inst, 0); theme->a_menu_selected = RrAppearanceNew(inst, 0); @@ -473,7 +474,7 @@ RrTheme* RrThemeNew(const RrInstance *inst, gchar *name, set_default_appearance(theme->a_menu); if (!read_appearance(db, inst, "menu.title.bg", theme->a_menu_title, - FALSE)) + TRUE)) set_default_appearance(theme->a_menu_title); if (!read_appearance(db, inst, "menu.items.active.bg", theme->a_menu_selected, @@ -636,6 +637,7 @@ RrTheme* RrThemeNew(const RrInstance *inst, gchar *name, theme->a_icon->surface.grad = theme->a_clear->surface.grad = theme->a_clear_tex->surface.grad = + theme->a_menu_text_title->surface.grad = theme->a_menu_normal->surface.grad = theme->a_menu_disabled->surface.grad = theme->a_menu_text_normal->surface.grad = @@ -736,10 +738,12 @@ RrTheme* RrThemeNew(const RrInstance *inst, gchar *name, theme->a_unfocused_label->texture[0].data.text.shadow_alpha = theme->title_unfocused_shadow_alpha; - theme->a_menu_title->texture[0].type = RR_TEXTURE_TEXT; - theme->a_menu_title->texture[0].data.text.justify = mtitlejust; - theme->a_menu_title->texture[0].data.text.font = theme->menu_title_font; - theme->a_menu_title->texture[0].data.text.color = theme->menu_title_color; + theme->a_menu_text_title->texture[0].type = RR_TEXTURE_TEXT; + theme->a_menu_text_title->texture[0].data.text.justify = mtitlejust; + theme->a_menu_text_title->texture[0].data.text.font = + theme->menu_title_font; + theme->a_menu_text_title->texture[0].data.text.color = + theme->menu_title_color; if (read_string(db, "menu.title.text.font", &str)) { char *p; @@ -750,8 +754,8 @@ RrTheme* RrThemeNew(const RrInstance *inst, gchar *name, i = parse_inline_number(p + strlen("shadowoffset=")); else i = 1; - theme->a_menu_title->texture[0].data.text.shadow_offset_x = i; - theme->a_menu_title->texture[0].data.text.shadow_offset_y = i; + theme->a_menu_text_title->texture[0].data.text.shadow_offset_x = i; + theme->a_menu_text_title->texture[0].data.text.shadow_offset_y = i; } if ((p = strstr(str, "shadowtint="))) { @@ -767,9 +771,9 @@ RrTheme* RrThemeNew(const RrInstance *inst, gchar *name, } } - theme->a_menu_title->texture[0].data.text.shadow_color = + theme->a_menu_text_title->texture[0].data.text.shadow_color = theme->menu_title_shadow_color; - theme->a_menu_title->texture[0].data.text.shadow_alpha = + theme->a_menu_text_title->texture[0].data.text.shadow_alpha = theme->menu_title_shadow_alpha; theme->a_menu_text_normal->texture[0].type = @@ -1042,7 +1046,7 @@ RrTheme* RrThemeNew(const RrInstance *inst, gchar *name, theme->a_unfocused_label->texture[0].data.text.shadow_offset_y)); theme->menu_title_font_height = RrFontHeight (theme->menu_title_font, - theme->a_menu_title->texture[0].data.text.shadow_offset_y); + theme->a_menu_text_title->texture[0].data.text.shadow_offset_y); theme->menu_font_height = RrFontHeight (theme->menu_font, theme->a_menu_text_normal->texture[0].data.text.shadow_offset_y); @@ -1199,6 +1203,7 @@ void RrThemeFree(RrTheme *theme) RrAppearanceFree(theme->a_unfocused_handle); RrAppearanceFree(theme->a_menu); RrAppearanceFree(theme->a_menu_title); + RrAppearanceFree(theme->a_menu_text_title); RrAppearanceFree(theme->a_menu_normal); RrAppearanceFree(theme->a_menu_disabled); RrAppearanceFree(theme->a_menu_selected); diff --git a/render/theme.h b/render/theme.h index acceaf5f..1960f43f 100644 --- a/render/theme.h +++ b/render/theme.h @@ -179,6 +179,7 @@ struct _RrTheme { RrAppearance *a_icon; RrAppearance *a_focused_handle; RrAppearance *a_unfocused_handle; + RrAppearance *a_menu_text_title; RrAppearance *a_menu_title; RrAppearance *a_menu; RrAppearance *a_menu_normal; -- 2.34.1