X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=openbox%2Fprompt.c;h=9fd56773a726ee3d04205f1fae0498bede663e09;hb=41dbce908a981214d2d61e813c17d9415f938d87;hp=9e91d249416e4a5a3416b8f3b86975986ae2b5a3;hpb=435df32acc55a3bc4cc8f9ba954ae21b65c7c69d;p=chaz%2Fopenbox diff --git a/openbox/prompt.c b/openbox/prompt.c index 9e91d249..9fd56773 100644 --- a/openbox/prompt.c +++ b/openbox/prompt.c @@ -50,13 +50,14 @@ static void prompt_layout(ObPrompt *self); static void render_all(ObPrompt *self); static void render_button(ObPrompt *self, ObPromptElement *e); static void prompt_resize(ObPrompt *self, gint w, gint h); +static void prompt_run_callback(ObPrompt *self, gint result); void prompt_startup(gboolean reconfig) { RrColor *c_button, *c_focus, *c_press, *c_pfocus; /* note: this is not a copy, don't free it */ - prompt_a_bg = ob_rr_theme->osd_hilite_bg; + prompt_a_bg = ob_rr_theme->osd_bg; prompt_a_button = RrAppearanceCopy(ob_rr_theme->a_focused_unpressed_close); prompt_a_focus = RrAppearanceCopy(ob_rr_theme->a_hover_focused_close); @@ -94,7 +95,7 @@ void prompt_startup(gboolean reconfig) prompt_a_button->texture[0].data.text.color = c_button; prompt_a_focus->texture[0].data.text.color = c_focus; prompt_a_press->texture[0].data.text.color = c_press; - prompt_a_pfocus->texture[0].data.text.color = c_press; + prompt_a_pfocus->texture[0].data.text.color = c_pfocus; prompt_a_focus->texture[1].data.lineart.color = c_focus; prompt_a_focus->texture[2].data.lineart.color = c_focus; @@ -121,6 +122,17 @@ void prompt_startup(gboolean reconfig) void prompt_shutdown(gboolean reconfig) { + GList *it; + + if (!reconfig) { + for (it = prompt_list; it; it = g_list_next(it)) { + ObPrompt *p = it->data; + if (p->cleanup) p->cleanup(p, p->data); + } + + g_assert(prompt_list == NULL); + } + RrAppearanceFree(prompt_a_button); RrAppearanceFree(prompt_a_focus); RrAppearanceFree(prompt_a_press); @@ -128,10 +140,11 @@ void prompt_shutdown(gboolean reconfig) RrAppearanceFree(prompt_a_msg); } -ObPrompt* prompt_new(const gchar *msg, +ObPrompt* prompt_new(const gchar *msg, const gchar *title, const ObPromptAnswer *answers, gint n_answers, gint default_result, gint cancel_result, - ObPromptCallback func, gpointer data) + ObPromptCallback func, ObPromptCleanup cleanup, + gpointer data) { ObPrompt *self; XSetWindowAttributes attrib; @@ -142,6 +155,7 @@ ObPrompt* prompt_new(const gchar *msg, self = g_new0(ObPrompt, 1); self->ref = 1; self->func = func; + self->cleanup = cleanup; self->data = data; self->default_result = default_result; self->cancel_result = cancel_result; @@ -152,11 +166,17 @@ ObPrompt* prompt_new(const gchar *msg, CopyFromParent, CWOverrideRedirect, &attrib); + self->ic = obt_keyboard_context_new(self->super.window, + self->super.window); /* make it a dialog type window */ OBT_PROP_SET32(self->super.window, NET_WM_WINDOW_TYPE, ATOM, OBT_PROP_ATOM(NET_WM_WINDOW_TYPE_DIALOG)); + /* set the window's title */ + if (title) + OBT_PROP_SETS(self->super.window, NET_WM_NAME, utf8, title); + /* listen for key presses on the window */ self->event_mask = KeyPressMask; @@ -216,8 +236,13 @@ void prompt_unref(ObPrompt *self) if (self && --self->ref == 0) { gint i; + if (self->mapped) + prompt_hide(self); + prompt_list = g_list_remove(prompt_list, self); + obt_keyboard_context_unref(self->ic); + for (i = 0; i < self->n_buttons; ++i) { window_remove(self->button[i].window); XDestroyWindow(obt_display, self->button[i].window); @@ -262,7 +287,6 @@ static void prompt_layout(ObPrompt *self) self->button[i].width = bw; self->button[i].height = bh; RrMinSize(prompt_a_focus, &bw, &bh); - g_print("button w %d h %d\n", bw, bh); self->button[i].width = MAX(self->button[i].width, bw); self->button[i].height = MAX(self->button[i].height, bh); RrMinSize(prompt_a_press, &bw, &bh); @@ -272,7 +296,6 @@ static void prompt_layout(ObPrompt *self) self->button[i].width = MAX(self->button[i].width, bw); self->button[i].height = MAX(self->button[i].height, bh); - self->button[i].width += BUTTON_HMARGIN * 2; self->button[i].height += BUTTON_VMARGIN * 2; @@ -386,18 +409,16 @@ static void setup_button_focus_tex(ObPromptElement *e, RrAppearance *a, a->texture[4].data.lineart.x2 = e->width - r - 1; a->texture[4].data.lineart.y1 = t; a->texture[4].data.lineart.y2 = e->height - b - 1; - - g_print("setting x2 %d\n", e->width - r - 1); } static void render_button(ObPrompt *self, ObPromptElement *e) { RrAppearance *a; - if (e->pressed && self->focus == e) a = prompt_a_pfocus; - else if (self->focus == e) a = prompt_a_focus; - else if (e->pressed) a = prompt_a_press; - else a = prompt_a_button; + if (e->hover && self->focus == e) a = prompt_a_pfocus; + else if (self->focus == e) a = prompt_a_focus; + else if (e->pressed) a = prompt_a_press; + else a = prompt_a_button; a->surface.parent = prompt_a_bg; a->surface.parentx = e->x; @@ -503,35 +524,35 @@ void prompt_hide(ObPrompt *self) gboolean prompt_key_event(ObPrompt *self, XEvent *e) { gboolean shift; - guint shift_mask; + guint shift_mask, mods; if (e->type != KeyPress) return FALSE; shift_mask = obt_keyboard_modkey_to_modmask(OBT_KEYBOARD_MODKEY_SHIFT); - shift = !!(e->xkey.state & shift_mask); + mods = obt_keyboard_only_modmasks(e->xkey.state); + shift = !!(mods & shift_mask); /* only accept shift */ - if (e->xkey.state != 0 && e->xkey.state != shift_mask) + if (mods != 0 && mods != shift_mask) return FALSE; - if (e->xkey.keycode == ob_keycode(OB_KEY_ESCAPE)) + if (ob_keycode_match(e->xkey.keycode, OB_KEY_ESCAPE)) prompt_cancel(self); - else if (e->xkey.keycode == ob_keycode(OB_KEY_RETURN) || - e->xkey.keycode == ob_keycode(OB_KEY_SPACE)) + else if (ob_keycode_match(e->xkey.keycode, OB_KEY_RETURN) || + ob_keycode_match(e->xkey.keycode, OB_KEY_SPACE)) { - if (self->func) self->func(self, self->focus->result, self->data); - prompt_hide(self); + prompt_run_callback(self, self->focus->result); } - else if (e->xkey.keycode == ob_keycode(OB_KEY_TAB) || - e->xkey.keycode == ob_keycode(OB_KEY_LEFT) || - e->xkey.keycode == ob_keycode(OB_KEY_RIGHT)) + else if (ob_keycode_match(e->xkey.keycode, OB_KEY_TAB) || + ob_keycode_match(e->xkey.keycode, OB_KEY_LEFT) || + ob_keycode_match(e->xkey.keycode, OB_KEY_RIGHT)) { gint i; gboolean left; ObPromptElement *oldfocus; - left = e->xkey.keycode == ob_keycode(OB_KEY_LEFT) || - (e->xkey.keycode == ob_keycode(OB_KEY_TAB) && shift); + left = ob_keycode_match(e->xkey.keycode, OB_KEY_LEFT) || + (ob_keycode_match(e->xkey.keycode, OB_KEY_TAB) && shift); oldfocus = self->focus; for (i = 0; i < self->n_buttons; ++i) @@ -571,27 +592,28 @@ gboolean prompt_mouse_event(ObPrompt *self, XEvent *e) oldfocus = self->focus; - but->pressed = TRUE; + but->pressed = but->hover = TRUE; self->focus = but; if (oldfocus != but) render_button(self, oldfocus); render_button(self, but); } else if (e->type == ButtonRelease) { - if (but->pressed) { - if (self->func) self->func(self, but->result, self->data); - prompt_hide(self); - } + if (but->hover) + prompt_run_callback(self, but->result); + but->pressed = FALSE; } else if (e->type == MotionNotify) { - gboolean press; + if (but->pressed) { + gboolean hover; - press = (e->xmotion.x >= 0 && e->xmotion.y >= 0 && - e->xmotion.x < but->width && e->xmotion.y < but->height); + hover = (e->xmotion.x >= 0 && e->xmotion.y >= 0 && + e->xmotion.x < but->width && e->xmotion.y < but->height); - if (press != but->pressed) { - but->pressed = press; - render_button(self, but); + if (hover != but->hover) { + but->hover = hover; + render_button(self, but); + } } } return TRUE; @@ -599,6 +621,41 @@ gboolean prompt_mouse_event(ObPrompt *self, XEvent *e) void prompt_cancel(ObPrompt *self) { - if (self->func) self->func(self, self->cancel_result, self->data); + prompt_run_callback(self, self->cancel_result); +} + +static gboolean prompt_show_message_cb(ObPrompt *p, int res, gpointer data) +{ + return TRUE; /* call the cleanup func */ +} + +static void prompt_show_message_cleanup(ObPrompt *p, gpointer data) +{ + prompt_unref(p); +} + +ObPrompt* prompt_show_message(const gchar *msg, const gchar *title, + const gchar *answer) +{ + ObPrompt *p; + ObPromptAnswer ans[] = { + { answer, 0 } + }; + + p = prompt_new(msg, title, ans, 1, 0, 0, + prompt_show_message_cb, prompt_show_message_cleanup, NULL); + prompt_show(p, NULL, FALSE); + return p; +} + +static void prompt_run_callback(ObPrompt *self, gint result) +{ + prompt_ref(self); + if (self->func) { + gboolean clean = self->func(self, self->focus->result, self->data); + if (clean && self->cleanup) + self->cleanup(self, self->data); + } prompt_hide(self); + prompt_unref(self); }