From 9e48d7468aacf18beea4cac759b97d300b0b2a0a Mon Sep 17 00:00:00 2001 From: Po Lu Date: Wed, 20 Apr 2022 07:37:19 +0000 Subject: [PATCH] Implement `above' z-group on Haiku * src/haiku_support.cc (class EmacsWindow): New field `z_group'. (RecomputeFeel): New function. (ParentTo, BWindow_set_override_redirect): Use that instead instead of manually juggling the window feel around. (BWindow_set_z_group): New function. * src/haiku_support.h (enum haiku_z_group): New enum. * src/haikufns.c (haiku_set_parent_frame): Clean up coding style. (haiku_set_z_group): New function. (haiku_create_frame): Always set z group after window creation, like on X. (haiku_frame_parm_handlers): Add `haiku_set_z_group'. --- src/haiku_support.cc | 48 +++++++++++++++++++++++++++++++++++++------ src/haiku_support.h | 30 +++++++++++++++++---------- src/haikufns.c | 49 ++++++++++++++++++++++++++++++++++++++++---- 3 files changed, 106 insertions(+), 21 deletions(-) diff --git a/src/haiku_support.cc b/src/haiku_support.cc index af37fe7a620..18a63182162 100644 --- a/src/haiku_support.cc +++ b/src/haiku_support.cc @@ -499,11 +499,13 @@ public: uint32 pre_override_redirect_workspaces; int window_id; bool *menus_begun = NULL; + enum haiku_z_group z_group; EmacsWindow () : BWindow (BRect (0, 0, 0, 0), "", B_TITLED_WINDOW_LOOK, B_NORMAL_WINDOW_FEEL, B_NO_SERVER_SIDE_WINDOW_MODIFIERS) { window_id = current_window_id++; + z_group = Z_GROUP_NONE; /* This pulse rate is used by scroll bars for repeating a button action while a button is held down. */ @@ -530,6 +532,19 @@ public: child_frame_lock.Unlock (); } + void + RecomputeFeel (void) + { + if (override_redirect_p) + SetFeel (kMenuWindowFeel); + else if (parent) + SetFeel (B_FLOATING_SUBSET_WINDOW_FEEL); + else if (z_group == Z_GROUP_ABOVE) + SetFeel (B_FLOATING_ALL_WINDOW_FEEL); + else + SetFeel (B_NORMAL_WINDOW_FEEL); + } + BRect CalculateZoomRect (void) { @@ -648,12 +663,17 @@ public: void Unparent (void) { + EmacsWindow *parent; + if (!child_frame_lock.Lock ()) gui_abort ("Failed to lock child frame state lock"); - this->SetFeel (B_NORMAL_WINDOW_FEEL); + + parent = this->parent; + this->parent = NULL; + RecomputeFeel (); UpwardsUnSubsetChildren (parent); this->RemoveFromSubset (this); - this->parent = NULL; + if (fullscreen_p) { fullscreen_p = 0; @@ -704,7 +724,7 @@ public: UnparentAndUnlink (); this->parent = window; - this->SetFeel (B_FLOATING_SUBSET_WINDOW_FEEL); + RecomputeFeel (); this->AddToSubset (this); if (!IsHidden () && this->parent) UpwardsSubsetChildren (parent); @@ -4116,9 +4136,8 @@ BWindow_set_override_redirect (void *window, bool override_redirect_p) if (override_redirect_p && !w->override_redirect_p) { w->override_redirect_p = true; - w->pre_override_redirect_feel = w->Feel (); w->pre_override_redirect_look = w->Look (); - w->SetFeel (kMenuWindowFeel); + w->RecomputeFeel (); w->SetLook (B_NO_BORDER_WINDOW_LOOK); w->pre_override_redirect_workspaces = w->Workspaces (); w->SetWorkspaces (B_ALL_WORKSPACES); @@ -4126,8 +4145,8 @@ BWindow_set_override_redirect (void *window, bool override_redirect_p) else if (w->override_redirect_p) { w->override_redirect_p = false; - w->SetFeel (w->pre_override_redirect_feel); w->SetLook (w->pre_override_redirect_look); + w->RecomputeFeel (); w->SetWorkspaces (w->pre_override_redirect_workspaces); } @@ -4286,3 +4305,20 @@ be_replay_menu_bar_event (void *menu_bar, messenger.SendMessage (&msg, &reply); return reply.what == BE_MENU_BAR_OPEN; } + +void +BWindow_set_z_group (void *window, enum haiku_z_group z_group) +{ + EmacsWindow *w = (EmacsWindow *) window; + + if (w->LockLooper ()) + { + if (w->z_group != z_group) + { + w->z_group = z_group; + w->RecomputeFeel (); + } + + w->UnlockLooper (); + } +} diff --git a/src/haiku_support.h b/src/haiku_support.h index 7f6f6e9b0d7..dfcf83bf3b7 100644 --- a/src/haiku_support.h +++ b/src/haiku_support.h @@ -38,21 +38,28 @@ along with GNU Emacs. If not, see . */ enum haiku_cursor { - CURSOR_ID_NO_CURSOR = 12, - CURSOR_ID_RESIZE_NORTH = 15, - CURSOR_ID_RESIZE_EAST = 16, - CURSOR_ID_RESIZE_SOUTH = 17, - CURSOR_ID_RESIZE_WEST = 18, - CURSOR_ID_RESIZE_NORTH_EAST = 19, - CURSOR_ID_RESIZE_NORTH_WEST = 20, - CURSOR_ID_RESIZE_SOUTH_EAST = 21, - CURSOR_ID_RESIZE_SOUTH_WEST = 22, - CURSOR_ID_RESIZE_NORTH_SOUTH = 23, - CURSOR_ID_RESIZE_EAST_WEST = 24, + CURSOR_ID_NO_CURSOR = 12, + CURSOR_ID_RESIZE_NORTH = 15, + CURSOR_ID_RESIZE_EAST = 16, + CURSOR_ID_RESIZE_SOUTH = 17, + CURSOR_ID_RESIZE_WEST = 18, + CURSOR_ID_RESIZE_NORTH_EAST = 19, + CURSOR_ID_RESIZE_NORTH_WEST = 20, + CURSOR_ID_RESIZE_SOUTH_EAST = 21, + CURSOR_ID_RESIZE_SOUTH_WEST = 22, + CURSOR_ID_RESIZE_NORTH_SOUTH = 23, + CURSOR_ID_RESIZE_EAST_WEST = 24, CURSOR_ID_RESIZE_NORTH_EAST_SOUTH_WEST = 25, CURSOR_ID_RESIZE_NORTH_WEST_SOUTH_EAST = 26 }; +enum haiku_z_group + { + Z_GROUP_ABOVE, + Z_GROUP_NONE, + Z_GROUP_BELOW, + }; + enum haiku_alert_type { HAIKU_EMPTY_ALERT = 0, @@ -459,6 +466,7 @@ extern void BWindow_send_behind (void *, void *); extern bool BWindow_is_active (void *); extern void BWindow_set_override_redirect (void *, bool); extern void BWindow_dimensions (void *, int *, int *); +extern void BWindow_set_z_group (void *, enum haiku_z_group); extern void BWindow_Flush (void *); extern void BFont_close (void *); diff --git a/src/haikufns.c b/src/haikufns.c index b19fdd5488a..5fca46c41bd 100644 --- a/src/haikufns.c +++ b/src/haikufns.c @@ -395,8 +395,8 @@ haiku_set_child_frame_border_width (struct frame *f, } static void -haiku_set_parent_frame (struct frame *f, - Lisp_Object new_value, Lisp_Object old_value) +haiku_set_parent_frame (struct frame *f, Lisp_Object new_value, + Lisp_Object old_value) { struct frame *p = NULL; block_input (); @@ -421,6 +421,7 @@ haiku_set_parent_frame (struct frame *f, EmacsWindow_unparent (FRAME_HAIKU_WINDOW (f)); FRAME_OUTPUT_DATA (f)->parent_desc = NULL; } + if (!NILP (new_value)) { EmacsWindow_parent_to (FRAME_HAIKU_WINDOW (f), @@ -436,6 +437,43 @@ haiku_set_parent_frame (struct frame *f, unblock_input (); } +static void +haiku_set_z_group (struct frame *f, Lisp_Object new_value, + Lisp_Object old_value) +{ + int rc; + + /* Tooltip frames can't have Z groups, since the window feel is + overridden during frame creation. */ + if (FRAME_TOOLTIP_P (f)) + return; + + rc = 1; + block_input (); + + if (NILP (new_value)) + { + BWindow_set_z_group (FRAME_HAIKU_WINDOW (f), Z_GROUP_NONE); + FRAME_Z_GROUP (f) = z_group_none; + } + else if (EQ (new_value, Qabove)) + { + BWindow_set_z_group (FRAME_HAIKU_WINDOW (f), Z_GROUP_ABOVE); + FRAME_Z_GROUP (f) = z_group_above; + } + else if (EQ (new_value, Qbelow)) + { + BWindow_set_z_group (FRAME_HAIKU_WINDOW (f), Z_GROUP_BELOW); + FRAME_Z_GROUP (f) = z_group_below; + } + else + rc = 0; + + unblock_input (); + if (!rc) + error ("Invalid z-group specification"); +} + static void haiku_explicitly_set_name (struct frame *f, Lisp_Object arg, Lisp_Object oldval) { @@ -726,11 +764,11 @@ haiku_create_frame (Lisp_Object parms) RES_TYPE_NUMBER); if (FIXNUMP (tem)) store_frame_param (f, Qmin_height, tem); + adjust_frame_size (f, FRAME_COLS (f) * FRAME_COLUMN_WIDTH (f), FRAME_LINES (f) * FRAME_LINE_HEIGHT (f), 5, 1, Qx_create_frame_1); - gui_default_parameter (f, parms, Qz_group, Qnil, NULL, NULL, RES_TYPE_SYMBOL); gui_default_parameter (f, parms, Qno_focus_on_map, Qnil, NULL, NULL, RES_TYPE_BOOLEAN); gui_default_parameter (f, parms, Qno_accept_focus, Qnil, @@ -875,6 +913,9 @@ haiku_create_frame (Lisp_Object parms) || !FRAME_LIVE_P (XFRAME (KVAR (kb, Vdefault_minibuffer_frame))))) kset_default_minibuffer_frame (kb, frame); + gui_default_parameter (f, parms, Qz_group, Qnil, + NULL, NULL, RES_TYPE_SYMBOL); + for (tem = parms; CONSP (tem); tem = XCDR (tem)) if (CONSP (XCAR (tem)) && !NILP (XCAR (XCAR (tem)))) fset_param_alist (f, Fcons (XCAR (tem), f->param_alist)); @@ -2638,7 +2679,7 @@ frame_parm_handler haiku_frame_parm_handlers[] = NULL, /* set skip taskbar */ haiku_set_no_focus_on_map, haiku_set_no_accept_focus, - NULL, /* set z group */ + haiku_set_z_group, haiku_set_override_redirect, gui_set_no_special_glyphs, gui_set_alpha_background, -- 2.39.2