From: Jeff Walsh Date: Thu, 9 Jan 2020 05:36:11 +0000 (+1100) Subject: Some work toward posframe on wayland X-Git-Tag: emacs-29.0.90~3816 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=c9e6b4486b6aee1e1011c81fdf0ef8270e237a15;p=emacs.git Some work toward posframe on wayland * src/pgtkterm.c (flip_cr_context, x_set_offset): update for new functionality (pgtk_set_window_size): remove dead code (x_set_parent_frame): cleanup trace code (pgtk_cr_update_surface_desired_size): add comment * src/pgtkmenu.c (Fmenu_or_popup_active_p): * src/pgtkfns.c (pgtk_frame_parm_handlers, Fx_create_frame): * src/gtkutil.c (xg_create_frame_widgets, x_wm_set_size_hint): * src/gtkutil.c (xg_create_frame_widgets): hacky GTK offsets taht will need better calculations Get parent frame's editor widget allocation for the offset Fix child-frame offsets for negative values Add some function comments around the new double context handling --- diff --git a/src/gtkutil.c b/src/gtkutil.c index 8cdbe3e4ad5..6573205e7b9 100644 --- a/src/gtkutil.c +++ b/src/gtkutil.c @@ -1353,6 +1353,7 @@ xg_create_frame_widgets (struct frame *f) #ifndef HAVE_GTK3 GtkRcStyle *style; #endif + GtkWindowType type = GTK_WINDOW_TOPLEVEL; char *title = 0; PGTK_TRACE("xg_create_frame_widgets."); @@ -1366,9 +1367,17 @@ xg_create_frame_widgets (struct frame *f) } else #endif - wtop = gtk_window_new (GTK_WINDOW_TOPLEVEL); + #ifdef HAVE_PGTK - gtk_widget_add_events(wtop, GDK_ALL_EVENTS_MASK); + if (!NILP(f->parent_frame)){ + type = GTK_WINDOW_POPUP; + } +#endif + + wtop = gtk_window_new (type); +#ifdef HAVE_PGTK + gtk_widget_add_events(wtop, GDK_ALL_EVENTS_MASK); + gtk_window_set_hide_titlebar_when_maximized(GTK_WINDOW(wtop), TRUE); #endif /* gtk_window_set_has_resize_grip is a Gtk+ 3.0 function but Ubuntu @@ -1494,7 +1503,7 @@ xg_create_frame_widgets (struct frame *f) #ifndef HAVE_PGTK gtk_widget_realize (wfixed); #else - gtk_widget_show_all(wtop); + // gtk_widget_show_all(wtop); #endif #ifndef HAVE_PGTK FRAME_X_WINDOW (f) = GTK_WIDGET_TO_X_WIN (wfixed); @@ -1712,10 +1721,8 @@ x_wm_set_size_hint (struct frame *f, long int flags, bool user_position) sizeof (size_hints)) != 0) { block_input (); -#ifndef HAVE_PGTK gtk_window_set_geometry_hints (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)), - NULL, &size_hints, hint_flags); -#endif + NULL, &size_hints, hint_flags); f->output_data.xp->size_hints = size_hints; f->output_data.xp->hint_flags = hint_flags; unblock_input (); diff --git a/src/pgtkfns.c b/src/pgtkfns.c index 2c8f73ebcb6..e7ab20897b7 100644 --- a/src/pgtkfns.c +++ b/src/pgtkfns.c @@ -915,7 +915,7 @@ frame_parm_handler pgtk_frame_parm_handlers[] = pgtk_set_tool_bar_position, 0, /* x_set_inhibit_double_buffering */ x_set_undecorated, - 0, /* x_set_parent_frame, */ + x_set_parent_frame, x_set_skip_taskbar, x_set_no_focus_on_map, x_set_no_accept_focus, @@ -1454,17 +1454,23 @@ This function is an internal primitive--use `make-frame' instead. */) gui_default_parameter (f, parms, Qalpha, Qnil, "alpha", "Alpha", RES_TYPE_NUMBER); -#if 0 if (!NILP (parent_frame)) { struct frame *p = XFRAME (parent_frame); block_input (); - XReparentWindow (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f), - FRAME_X_WINDOW (p), f->left_pos, f->top_pos); + PGTK_TRACE ("x_set_parent_frame x: %d, y: %d", f->left_pos, f->top_pos); + gtk_window_set_transient_for(GTK_WINDOW(FRAME_GTK_OUTER_WIDGET(f)), + GTK_WINDOW(FRAME_GTK_OUTER_WIDGET(p))); + gtk_window_set_attached_to(GTK_WINDOW(FRAME_GTK_OUTER_WIDGET(f)), + FRAME_GTK_WIDGET(p)); + gtk_window_set_destroy_with_parent(GTK_WINDOW(FRAME_GTK_OUTER_WIDGET(f)), + TRUE); + gtk_widget_show_all(FRAME_GTK_OUTER_WIDGET(f)); unblock_input (); } -#endif + + gtk_widget_show_all(FRAME_GTK_OUTER_WIDGET(f)); gui_default_parameter (f, parms, Qno_focus_on_map, Qnil, NULL, NULL, RES_TYPE_BOOLEAN); @@ -3153,7 +3159,7 @@ When using Gtk+ tooltips, the tooltip face is not used. */); DEFSYM (Qreverse_landscape, "reverse-landscape"); } -#ifdef PGTK_DEBUG + #include #include @@ -3175,7 +3181,7 @@ void pgtk_log(const char *file, int lineno, const char *fmt, ...) va_end(ap); fputc('\n', stderr); } - +#ifdef PGTK_DEBUG void pgtk_backtrace(const char *file, int lineno) { Lisp_Object bt = make_uninit_vector(10); diff --git a/src/pgtkmenu.c b/src/pgtkmenu.c index bbe47ddad6b..9148504f8ee 100644 --- a/src/pgtkmenu.c +++ b/src/pgtkmenu.c @@ -457,9 +457,8 @@ DEFUN ("menu-or-popup-active-p", Fmenu_or_popup_active_p, Smenu_or_popup_active_ doc: /* SKIP: real doc in xmenu.c. */) (void) { - struct frame *f; - f = SELECTED_FRAME (); - // return (f->output_data.pgtk->menubar_active > 0) ? Qt : Qnil; + /* struct frame *f = SELECTED_FRAME (); */ + /* return (f->output_data.pgtk->menubar_active > 0) ? Qt : Qnil; */ return Qnil; } diff --git a/src/pgtkterm.c b/src/pgtkterm.c index 86ebf864a77..d7ac68c32f2 100644 --- a/src/pgtkterm.c +++ b/src/pgtkterm.c @@ -38,6 +38,7 @@ along with GNU Emacs. If not, see . */ #include "lisp.h" #include "blockinput.h" +#include "frame.h" #include "sysselect.h" #include "gtkutil.h" #include "systime.h" @@ -97,6 +98,13 @@ static void pgtk_clip_to_row (struct window *w, struct glyph_row *row, static struct frame * pgtk_any_window_to_frame (GdkWindow *window); +/* + * This is not a flip context in the same sense as gpu rendering + * scences, it only occurs when a new context was required due to a + * resize or other fundamental change. This is called when that + * context's surface has completed drawing + */ + static void flip_cr_context(struct frame *f) { PGTK_TRACE("flip_cr_context"); @@ -356,23 +364,36 @@ x_set_offset (struct frame *f, int xoff, int yoff, int change_gravity) External: Position the window -------------------------------------------------------------------------- */ { - /* not working on wayland. */ - PGTK_TRACE("x_set_offset: %d,%d,%d.", xoff, yoff, change_gravity); - if (change_gravity > 0) - { - PGTK_TRACE("x_set_offset: change_gravity > 0"); - f->top_pos = yoff; + struct frame *parent = FRAME_PARENT_FRAME(f); + GtkAllocation a = {0}; + if (change_gravity > 0) { + if (parent) { + /* determing the "height" of the titlebar, by finding the + location of the "emacsfixed" widget on the surface/window */ + GtkWidget *w = FRAME_GTK_WIDGET(parent); + gtk_widget_get_allocation(w, &a); + } + + f->size_hint_flags &= ~ (XNegative | YNegative); + /* if the value is negative, don't include the titlebar offset */ + if (xoff < 0) { + f->size_hint_flags |= XNegative; f->left_pos = xoff; - f->size_hint_flags &= ~ (XNegative | YNegative); - if (xoff < 0) - f->size_hint_flags |= XNegative; - if (yoff < 0) - f->size_hint_flags |= YNegative; - f->win_gravity = NorthWestGravity; + } else { + f->left_pos = xoff + a.x; //~25 } + if (yoff < 0){ + f->size_hint_flags |= YNegative; + f->top_pos = yoff; + } else { + f->top_pos = yoff + a.y; //~60 + } + f->win_gravity = NorthWestGravity; + } + x_calc_absolute_position (f); block_input (); @@ -431,8 +452,6 @@ pgtk_set_window_size (struct frame *f, for (GtkWidget *w = FRAME_GTK_WIDGET(f); w != NULL; w = gtk_widget_get_parent(w)) { gint wd, hi; gtk_widget_get_size_request(w, &wd, &hi); - GtkAllocation alloc; - gtk_widget_get_allocation(w, &alloc); } f->output_data.pgtk->preferred_width = pixelwidth; @@ -673,6 +692,56 @@ x_display_pixel_width (struct pgtk_display_info *dpyinfo) return gdk_screen_get_width(gscr); } +void +x_set_parent_frame (struct frame *f, Lisp_Object new_value, Lisp_Object old_value) +/* -------------------------------------------------------------------------- + Set frame F's `parent-frame' parameter. If non-nil, make F a child + frame of the frame specified by that parameter. Technically, this + makes F's window-system window a child window of the parent frame's + window-system window. If nil, make F's window-system window a + top-level window--a child of its display's root window. + + A child frame's `left' and `top' parameters specify positions + relative to the top-left corner of its parent frame's native + rectangle. On macOS moving a parent frame moves all its child + frames too, keeping their position relative to the parent + unaltered. When a parent frame is iconified or made invisible, its + child frames are made invisible. When a parent frame is deleted, + its child frames are deleted too. + + Whether a child frame has a tool bar may be window-system or window + manager dependent. It's advisable to disable it via the frame + parameter settings. + + Some window managers may not honor this parameter. + -------------------------------------------------------------------------- */ +{ + struct frame *p = NULL; + PGTK_TRACE ("x_set_parent_frame x: %d, y: %d", f->left_pos, f->top_pos); + + if (!NILP (new_value) + && (!FRAMEP (new_value) + || !FRAME_LIVE_P (p = XFRAME (new_value)) + || !FRAME_PGTK_P (p))) + { + store_frame_param (f, Qparent_frame, old_value); + error ("Invalid specification of `parent-frame'"); + } + + if (p != FRAME_PARENT_FRAME (f) + && (p != NULL)) + { + block_input (); + gtk_window_set_transient_for(FRAME_NATIVE_WINDOW(f), FRAME_NATIVE_WINDOW(p)); + gtk_window_set_attached_to(FRAME_NATIVE_WINDOW(f), FRAME_GTK_WIDGET(p)); + gtk_window_move(FRAME_NATIVE_WINDOW(f), f->left_pos, f->top_pos); + gtk_window_set_keep_above(FRAME_NATIVE_WINDOW(f), true); + unblock_input (); + + fset_parent_frame (f, new_value); + } +} + void x_set_no_focus_on_map (struct frame *f, Lisp_Object new_value, Lisp_Object old_value) @@ -2627,7 +2696,6 @@ pgtk_draw_window_cursor (struct window *w, struct glyph_row *glyph_row, int x, { PGTK_TRACE("draw_window_cursor: %d, %d, %d, %d, %d, %d.", x, y, cursor_type, cursor_width, on_p, active_p); - if (on_p) { w->phys_cursor_type = cursor_type; @@ -2676,6 +2744,7 @@ pgtk_draw_window_cursor (struct window *w, struct glyph_row *glyph_row, int x, xic_set_preeditarea (w, x, y); #endif } + } static void @@ -6538,10 +6607,16 @@ If set to a non-float value, there will be no wait at all. */); /* Tell Emacs about this window system. */ Fprovide (Qpgtk, Qnil); - } - +/* Cairo does not allow resizing a surface/context after it is + * created, so we need to trash the old context, create a new context + * on the next cr_clip_begin with the new dimensions and request a + * re-draw. + * + * This Will leave the active context available to present on screen + * until a redrawn frame is completed. + */ void pgtk_cr_update_surface_desired_size (struct frame *f, int width, int height) {