emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

feature/pgtk c9e6b44 044/100: Some work toward posframe on wayland


From: Yuuki Harano
Subject: feature/pgtk c9e6b44 044/100: Some work toward posframe on wayland
Date: Tue, 24 Nov 2020 08:02:34 -0500 (EST)

branch: feature/pgtk
commit c9e6b4486b6aee1e1011c81fdf0ef8270e237a15
Author: Jeff Walsh <jawalsh@localhost.localdomain>
Commit: Jeff Walsh <jeff.walsh@drtusers-MacBook-Pro.local>

    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
---
 src/gtkutil.c  |  19 ++++++----
 src/pgtkfns.c  |  20 +++++++----
 src/pgtkmenu.c |   5 ++-
 src/pgtkterm.c | 109 ++++++++++++++++++++++++++++++++++++++++++++++++---------
 4 files changed, 120 insertions(+), 33 deletions(-)

diff --git a/src/gtkutil.c b/src/gtkutil.c
index 8cdbe3e..6573205 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 2c8f73e..e7ab208 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 <stdarg.h>
 #include <time.h>
@@ -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 bbe47dd..9148504 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 86ebf86..d7ac68c 100644
--- a/src/pgtkterm.c
+++ b/src/pgtkterm.c
@@ -38,6 +38,7 @@ along with GNU Emacs.  If not, see 
<https://www.gnu.org/licenses/>.  */
 
 #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)
 {



reply via email to

[Prev in Thread] Current Thread [Next in Thread]