* src/haiku_io.c (haiku_len): Handle new event `MENU_BAR_CLICK'.
* src/haiku_support.cc (class EmacsWindow): Remove most of the
menu bar cv stuff.
(MessageReceived): Handle REPLAY_MENU_BAR message.
(EmacsWindow_signal_menu_update_complete): Delete function.
(be_replay_menu_bar_event): New function.
* src/haiku_support.h (enum haiku_event_type): New event type
`MENU_BAR_CLICK'.
(struct haiku_menu_bar_click_event): New struct.
* src/haikumenu.c (haiku_activate_menubar): New function.
* src/haikuterm.c (haiku_read_socket): Save a
MENU_BAR_ACTIVATE_EVENT and the menu bar click event instead of
handling the menu bar update synchronously.
(haiku_create_terminal): Set `activate_menubar_hook'.
(syms_of_haikuterm): Remove extraneous newline.
* src/haikuterm.h (struct haiku_output): New field
`saved_menu_event'.
return sizeof (struct haiku_wheel_move_event);
case MENU_BAR_RESIZE:
return sizeof (struct haiku_menu_bar_resize_event);
+ case MENU_BAR_CLICK:
+ return sizeof (struct haiku_menu_bar_click_event);
case MENU_BAR_OPEN:
case MENU_BAR_CLOSE:
return sizeof (struct haiku_menu_bar_state_event);
SHOW_MENU_BAR = 3004,
BE_MENU_BAR_OPEN = 3005,
QUIT_APPLICATION = 3006,
+ REPLAY_MENU_BAR = 3007,
};
/* X11 keysyms that we use. */
window_look pre_override_redirect_look;
window_feel pre_override_redirect_feel;
uint32 pre_override_redirect_workspaces;
- pthread_mutex_t menu_update_mutex = PTHREAD_MUTEX_INITIALIZER;
- pthread_cond_t menu_update_cv = PTHREAD_COND_INITIALIZER;
- bool menu_updated_p = false;
int window_id;
bool *menus_begun = NULL;
if (this->parent)
UnparentAndUnlink ();
child_frame_lock.Unlock ();
-
- pthread_cond_destroy (&menu_update_cv);
- pthread_mutex_destroy (&menu_update_mutex);
}
BRect
}
void
- MenusBeginning ()
+ MenusBeginning (void)
{
struct haiku_menu_bar_state_event rq;
- int lock_count;
rq.window = this;
- lock_count = 0;
-
if (!menus_begun)
- {
- haiku_write (MENU_BAR_OPEN, &rq);
- while (IsLocked ())
- {
- ++lock_count;
- UnlockLooper ();
- }
- pthread_mutex_lock (&menu_update_mutex);
- while (!menu_updated_p)
- pthread_cond_wait (&menu_update_cv,
- &menu_update_mutex);
- menu_updated_p = false;
- pthread_mutex_unlock (&menu_update_mutex);
- for (; lock_count; --lock_count)
- {
- if (!LockLooper ())
- gui_abort ("Failed to lock after cv signal denoting menu update");
- }
- }
+ haiku_write (MENU_BAR_OPEN, &rq);
else
*menus_begun = true;
class EmacsMenuBar : public BMenuBar
{
+ bool tracking_p;
+
public:
EmacsMenuBar () : BMenuBar (BRect (0, 0, 0, 0), NULL)
{
BMenuBar::FrameResized (newWidth, newHeight);
}
+ void
+ MouseDown (BPoint point)
+ {
+ struct haiku_menu_bar_click_event rq;
+ EmacsWindow *ew = (EmacsWindow *) Window ();
+
+ rq.window = ew;
+ rq.x = std::lrint (point.x);
+ rq.y = std::lrint (point.y);
+
+ if (!ew->menu_bar_active_p)
+ haiku_write (MENU_BAR_CLICK, &rq);
+ else
+ BMenuBar::MouseDown (point);
+ }
+
void
MouseMoved (BPoint point, uint32 transit, const BMessage *msg)
{
else
msg->SendReply (BE_MENU_BAR_OPEN);
}
+ else if (msg->what == REPLAY_MENU_BAR)
+ {
+ if (msg->FindPoint ("emacs:point", &pt) == B_OK)
+ BMenuBar::MouseDown (pt);
+ }
else
BMenuBar::MessageReceived (msg);
}
return value;
}
-void
-EmacsWindow_signal_menu_update_complete (void *window)
-{
- EmacsWindow *w = (EmacsWindow *) window;
-
- pthread_mutex_lock (&w->menu_update_mutex);
- w->menu_updated_p = true;
- pthread_cond_signal (&w->menu_update_cv);
- pthread_mutex_unlock (&w->menu_update_mutex);
-}
-
void
BMessage_delete (void *message)
{
{
return drag_and_drop_in_progress;
}
+
+void
+be_replay_menu_bar_event (void *menu_bar,
+ struct haiku_menu_bar_click_event *event)
+{
+ BMenuBar *m = (BMenuBar *) menu_bar;
+ BMessenger messenger (m);
+ BMessage msg (REPLAY_MENU_BAR);
+
+ msg.AddPoint ("emacs:point", BPoint (event->x, event->y));
+ messenger.SendMessage (&msg);
+}
SCROLL_BAR_DRAG_EVENT,
WHEEL_MOVE_EVENT,
MENU_BAR_RESIZE,
+ MENU_BAR_CLICK,
MENU_BAR_OPEN,
MENU_BAR_SELECT_EVENT,
MENU_BAR_CLOSE,
int x, y;
};
+struct haiku_menu_bar_click_event
+{
+ void *window;
+ int x, y;
+};
+
struct haiku_button_event
{
void *window;
extern void EmacsWindow_move_weak_child (void *, void *, int, int);
extern void EmacsWindow_make_fullscreen (void *, int);
extern void EmacsWindow_unzoom (void *);
-extern void EmacsWindow_signal_menu_update_complete (void *);
extern void be_get_version_string (char *, int);
extern int be_get_display_planes (void);
bool (*) (void));
extern bool be_drag_and_drop_in_progress (void);
+extern void be_replay_menu_bar_event (void *, struct haiku_menu_bar_click_event *);
+
#ifdef __cplusplus
extern void *find_appropriate_view_for_draw (void *);
}
return Qnil;
}
+void
+haiku_activate_menubar (struct frame *f)
+{
+ int rc;
+
+ if (!FRAME_HAIKU_MENU_BAR (f))
+ return;
+
+ set_frame_menubar (f, true);
+
+ if (FRAME_OUTPUT_DATA (f)->saved_menu_event)
+ {
+ block_input ();
+ be_replay_menu_bar_event (FRAME_HAIKU_MENU_BAR (f),
+ FRAME_OUTPUT_DATA (f)->saved_menu_event);
+ xfree (FRAME_OUTPUT_DATA (f)->saved_menu_event);
+ FRAME_OUTPUT_DATA (f)->saved_menu_event = NULL;
+ unblock_input ();
+ }
+ else
+ {
+ block_input ();
+ rc = BMenuBar_start_tracking (FRAME_HAIKU_MENU_BAR (f));
+ unblock_input ();
+
+ if (!rc)
+ return;
+
+ FRAME_OUTPUT_DATA (f)->menu_bar_open_p = 1;
+ popup_activated_p += 1;
+ }
+}
+
void
syms_of_haikumenu (void)
{
}
break;
}
+ case MENU_BAR_CLICK:
+ {
+ struct haiku_menu_bar_click_event *b = buf;
+ struct frame *f = haiku_window_to_frame (b->window);
+
+ if (!f || !FRAME_EXTERNAL_MENU_BAR (f))
+ continue;
+
+ if (!FRAME_OUTPUT_DATA (f)->saved_menu_event)
+ FRAME_OUTPUT_DATA (f)->saved_menu_event = xmalloc (sizeof *b);
+ *FRAME_OUTPUT_DATA (f)->saved_menu_event = *b;
+ inev.kind = MENU_BAR_ACTIVATE_EVENT;
+ XSETFRAME (inev.frame_or_window, f);
+ break;
+ }
case MENU_BAR_OPEN:
case MENU_BAR_CLOSE:
{
struct haiku_menu_bar_state_event *b = buf;
struct frame *f = haiku_window_to_frame (b->window);
- int was_waiting_for_input_p;
if (!f || !FRAME_EXTERNAL_MENU_BAR (f))
continue;
if (type == MENU_BAR_OPEN)
{
- was_waiting_for_input_p = waiting_for_input;
- if (waiting_for_input)
- waiting_for_input = 0;
-
- set_frame_menubar (f, 1);
- waiting_for_input = was_waiting_for_input_p;
-
FRAME_OUTPUT_DATA (f)->menu_bar_open_p = 1;
popup_activated_p += 1;
-
- EmacsWindow_signal_menu_update_complete (b->window);
}
else
{
if (!popup_activated_p)
emacs_abort ();
+
if (FRAME_OUTPUT_DATA (f)->menu_bar_open_p)
{
FRAME_OUTPUT_DATA (f)->menu_bar_open_p = 0;
terminal->toggle_invisible_pointer_hook = haiku_toggle_invisible_pointer;
terminal->fullscreen_hook = haiku_fullscreen;
terminal->toolkit_position_hook = haiku_toolkit_position;
+ terminal->activate_menubar_hook = haiku_activate_menubar;
return terminal;
}
Setting it to any other value is equivalent to `shift'. */);
Vhaiku_shift_keysym = Qnil;
-
DEFSYM (Qx_use_underline_position_properties,
"x-use-underline-position-properties");
/* The default cursor foreground color. */
uint32_t cursor_fg;
+
+ /* If non-NULL, the last menu bar click event received. */
+ struct haiku_menu_bar_click_event *saved_menu_event;
};
struct x_output
extern Lisp_Object haiku_menu_show (struct frame *, int, int, int,
Lisp_Object, const char **);
extern Lisp_Object haiku_popup_dialog (struct frame *, Lisp_Object, Lisp_Object);
+extern void haiku_activate_menubar (struct frame *);
extern void haiku_note_drag_motion (void);
extern void initialize_frame_menubar (struct frame *);