mirror of
git://git.sv.gnu.org/emacs.git
synced 2026-01-09 21:20:45 -08:00
Fix hangs when clicking on Haiku menu bar to activate frame
* 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'.
This commit is contained in:
parent
3dc73569b4
commit
e8b0808e20
6 changed files with 103 additions and 52 deletions
|
|
@ -79,6 +79,8 @@ haiku_len (enum haiku_event_type type)
|
|||
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);
|
||||
|
|
|
|||
|
|
@ -91,6 +91,7 @@ enum
|
|||
SHOW_MENU_BAR = 3004,
|
||||
BE_MENU_BAR_OPEN = 3005,
|
||||
QUIT_APPLICATION = 3006,
|
||||
REPLAY_MENU_BAR = 3007,
|
||||
};
|
||||
|
||||
/* X11 keysyms that we use. */
|
||||
|
|
@ -496,9 +497,6 @@ public:
|
|||
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;
|
||||
|
||||
|
|
@ -530,9 +528,6 @@ public:
|
|||
if (this->parent)
|
||||
UnparentAndUnlink ();
|
||||
child_frame_lock.Unlock ();
|
||||
|
||||
pthread_cond_destroy (&menu_update_cv);
|
||||
pthread_mutex_destroy (&menu_update_mutex);
|
||||
}
|
||||
|
||||
BRect
|
||||
|
|
@ -977,34 +972,13 @@ public:
|
|||
}
|
||||
|
||||
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;
|
||||
|
||||
|
|
@ -1278,6 +1252,8 @@ public:
|
|||
|
||||
class EmacsMenuBar : public BMenuBar
|
||||
{
|
||||
bool tracking_p;
|
||||
|
||||
public:
|
||||
EmacsMenuBar () : BMenuBar (BRect (0, 0, 0, 0), NULL)
|
||||
{
|
||||
|
|
@ -1303,6 +1279,22 @@ public:
|
|||
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)
|
||||
{
|
||||
|
|
@ -1351,6 +1343,11 @@ public:
|
|||
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);
|
||||
}
|
||||
|
|
@ -4147,17 +4144,6 @@ be_find_setting (const char *name)
|
|||
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)
|
||||
{
|
||||
|
|
@ -4274,3 +4260,15 @@ be_drag_and_drop_in_progress (void)
|
|||
{
|
||||
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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -80,6 +80,7 @@ enum haiku_event_type
|
|||
SCROLL_BAR_DRAG_EVENT,
|
||||
WHEEL_MOVE_EVENT,
|
||||
MENU_BAR_RESIZE,
|
||||
MENU_BAR_CLICK,
|
||||
MENU_BAR_OPEN,
|
||||
MENU_BAR_SELECT_EVENT,
|
||||
MENU_BAR_CLOSE,
|
||||
|
|
@ -168,6 +169,12 @@ struct haiku_menu_bar_left_event
|
|||
int x, y;
|
||||
};
|
||||
|
||||
struct haiku_menu_bar_click_event
|
||||
{
|
||||
void *window;
|
||||
int x, y;
|
||||
};
|
||||
|
||||
struct haiku_button_event
|
||||
{
|
||||
void *window;
|
||||
|
|
@ -577,7 +584,6 @@ extern void EmacsWindow_unparent (void *);
|
|||
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);
|
||||
|
|
@ -630,6 +636,8 @@ extern bool be_drag_message (void *, void *, bool, void (*) (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 *);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -774,6 +774,39 @@ the position of the last non-menu event instead. */)
|
|||
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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -3475,34 +3475,40 @@ haiku_read_socket (struct terminal *terminal, struct input_event *hold_quit)
|
|||
}
|
||||
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;
|
||||
|
|
@ -3873,6 +3879,7 @@ haiku_create_terminal (struct haiku_display_info *dpyinfo)
|
|||
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;
|
||||
}
|
||||
|
|
@ -4184,7 +4191,6 @@ This is either one of the symbols `shift', `control', `command', and
|
|||
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");
|
||||
|
||||
|
|
|
|||
|
|
@ -176,6 +176,9 @@ struct haiku_output
|
|||
|
||||
/* 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
|
||||
|
|
@ -291,6 +294,7 @@ extern void haiku_put_pixel (haiku, int, int, unsigned long);
|
|||
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 *);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue