From: Po Lu Date: Tue, 4 Jan 2022 05:22:56 +0000 (+0000) Subject: Find a way to make restacking frames work on Haiku X-Git-Tag: emacs-29.0.90~3273 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=f3481f21f710ab41980623728917704bb25b3ae5;p=emacs.git Find a way to make restacking frames work on Haiku * doc/lispref/frames.texi (Raising and Lowering): Update documentation to reflect that restacking frames is now supported on Haiku. * lisp/frame.el (haiku-frame-restack): New declaration. (frame-restack): Use `haiku-frame-restack' on Haiku. * src/haiku_support.cc (BWindow_send_behind): * src/haiku_support.h (BWindow_send_behind): * src/haikufns.c (Fhaiku_frame_restack): New functions. (syms_of_haikufns): New subr `haiku-frame-restack'. --- diff --git a/doc/lispref/frames.texi b/doc/lispref/frames.texi index bb5d4bf2919..ceaa11529f7 100644 --- a/doc/lispref/frames.texi +++ b/doc/lispref/frames.texi @@ -3165,8 +3165,7 @@ that if both frames are visible and their display areas overlap, third argument @var{above} is non-@code{nil}, this function restacks @var{frame1} above @var{frame2}. This means that if both frames are visible and their display areas overlap, @var{frame1} will (partially) -obscure @var{frame2}.@footnote{Restacking frames is not supported on -Haiku, due to limitations imposed by the system.} +obscure @var{frame2}. Technically, this function may be thought of as an atomic action performed in two steps: The first step removes @var{frame1}'s diff --git a/lisp/frame.el b/lisp/frame.el index 60ef563e591..62b73f3157b 100644 --- a/lisp/frame.el +++ b/lisp/frame.el @@ -2019,6 +2019,7 @@ Return nil if DISPLAY contains no Emacs frame." (declare-function w32-frame-restack "w32fns.c" (frame1 frame2 &optional above)) (declare-function ns-frame-restack "nsfns.m" (frame1 frame2 &optional above)) (declare-function pgtk-frame-restack "pgtkfns.c" (frame1 frame2 &optional above)) +(declare-function haiku-frame-restack "haikufns.c" (frame1 frame2 &optional above)) (defun frame-restack (frame1 frame2 &optional above) "Restack FRAME1 below FRAME2. @@ -2049,6 +2050,8 @@ Some window managers may refuse to restack windows." (w32-frame-restack frame1 frame2 above)) ((eq frame-type 'ns) (ns-frame-restack frame1 frame2 above)) + ((eq frame-type 'haiku) + (haiku-frame-restack frame1 frame2 above)) ((eq frame-type 'pgtk) (pgtk-frame-restack frame1 frame2 above)))) (error "Cannot restack frames"))) diff --git a/src/haiku_support.cc b/src/haiku_support.cc index 74e9765903e..effd4c33a92 100644 --- a/src/haiku_support.cc +++ b/src/haiku_support.cc @@ -2990,3 +2990,15 @@ BWindow_set_size_alignment (void *window, int align_width, int align_height) #endif w->UnlockLooper (); } + +void +BWindow_send_behind (void *window, void *other_window) +{ + BWindow *w = (BWindow *) window; + BWindow *other = (BWindow *) other_window; + + if (!w->LockLooper ()) + gui_abort ("Failed to lock window in order to send it behind another"); + w->SendBehind (other); + w->UnlockLooper (); +} diff --git a/src/haiku_support.h b/src/haiku_support.h index dd5e168d140..2b61ec1ac1e 100644 --- a/src/haiku_support.h +++ b/src/haiku_support.h @@ -823,6 +823,9 @@ extern "C" extern void BWindow_sync (void *window); + extern void + BWindow_send_behind (void *window, void *other_window); + #ifdef __cplusplus extern void * find_appropriate_view_for_draw (void *vw); diff --git a/src/haikufns.c b/src/haikufns.c index 6cd12f129c6..0b7972f945c 100644 --- a/src/haikufns.c +++ b/src/haikufns.c @@ -2321,6 +2321,39 @@ DEFUN ("x-display-save-under", Fx_display_save_under, return Qnil; } +DEFUN ("haiku-frame-restack", Fhaiku_frame_restack, Shaiku_frame_restack, 2, 3, 0, + doc: /* Restack FRAME1 below FRAME2. +This means that if both frames are visible and the display areas of +these frames overlap, FRAME2 (partially) obscures FRAME1. If optional +third argument ABOVE is non-nil, restack FRAME1 above FRAME2. This +means that if both frames are visible and the display areas of these +frames overlap, FRAME1 (partially) obscures FRAME2. + +Some window managers may refuse to restack windows. */) + (Lisp_Object frame1, Lisp_Object frame2, Lisp_Object above) +{ + struct frame *f1 = decode_live_frame (frame1); + struct frame *f2 = decode_live_frame (frame2); + + check_window_system (f1); + check_window_system (f2); + + block_input (); + + if (NILP (above)) + BWindow_send_behind (FRAME_HAIKU_WINDOW (f1), + FRAME_HAIKU_WINDOW (f2)); + else + BWindow_send_behind (FRAME_HAIKU_WINDOW (f2), + FRAME_HAIKU_WINDOW (f1)); + BWindow_sync (FRAME_HAIKU_WINDOW (f1)); + BWindow_sync (FRAME_HAIKU_WINDOW (f2)); + + unblock_input (); + + return Qnil; +} + frame_parm_handler haiku_frame_parm_handlers[] = { gui_set_autoraise, @@ -2415,6 +2448,7 @@ syms_of_haikufns (void) defsubr (&Shaiku_put_resource); defsubr (&Shaiku_frame_list_z_order); defsubr (&Sx_display_save_under); + defsubr (&Shaiku_frame_restack); tip_timer = Qnil; staticpro (&tip_timer);