emacs-diffs
[Top][All Lists]
Advanced

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

feature/pgtk 9eb35f9 033/100: experimental support of tab-bar.


From: Yuuki Harano
Subject: feature/pgtk 9eb35f9 033/100: experimental support of tab-bar.
Date: Tue, 24 Nov 2020 08:02:31 -0500 (EST)

branch: feature/pgtk
commit 9eb35f9996197476fd300be1b8dd62c6b791678e
Author: Yuuki Harano <masm+github@masm11.me>
Commit: Jeff Walsh <fejfighter@gmail.com>

    experimental support of tab-bar.
    
    * src/window.h: compile conditional
    
    * src/pgtkterm.h: function decls
    
    * src/pgtkterm.c (x_draw_image_relief, pgtk_create_terminal)
    (motion_notify_event, button_event): tabbar support
    
    * src/pgtkfns.c (x_set_tab_bar_lines, x_change_tab_bar_height)
    (pgtk_frame_parm_handlers, Fx_create_frame, frame_geometry): tabbar support
    
    余計なイベントが生成されていたのを修正。
---
 src/pgtkfns.c  | 104 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 src/pgtkterm.c |  46 +++++++++++++++++++++++--
 src/pgtkterm.h |   2 ++
 src/window.h   |   2 +-
 4 files changed, 149 insertions(+), 5 deletions(-)

diff --git a/src/pgtkfns.c b/src/pgtkfns.c
index 88702f17..090ebf5 100644
--- a/src/pgtkfns.c
+++ b/src/pgtkfns.c
@@ -513,6 +513,93 @@ x_set_menu_bar_lines (struct frame *f, Lisp_Object value, 
Lisp_Object oldval)
   adjust_frame_glyphs (f);
 }
 
+/* Set the number of lines used for the tab bar of frame F to VALUE.
+   VALUE not an integer, or < 0 means set the lines to zero.  OLDVAL
+   is the old number of tab bar lines.  This function changes the
+   height of all windows on frame F to match the new tab bar height.
+   The frame's height doesn't change.  */
+
+static void
+x_set_tab_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)
+{
+  int nlines;
+
+  /* Treat tab bars like menu bars.  */
+  if (FRAME_MINIBUF_ONLY_P (f))
+    return;
+
+  /* Use VALUE only if an int >= 0.  */
+  if (RANGED_FIXNUMP (0, value, INT_MAX))
+    nlines = XFIXNAT (value);
+  else
+    nlines = 0;
+
+  x_change_tab_bar_height (f, nlines * FRAME_LINE_HEIGHT (f));
+}
+
+
+/* Set the pixel height of the tab bar of frame F to HEIGHT.  */
+void
+x_change_tab_bar_height (struct frame *f, int height)
+{
+  int unit = FRAME_LINE_HEIGHT (f);
+  int old_height = FRAME_TAB_BAR_HEIGHT (f);
+  int lines = (height + unit - 1) / unit;
+  Lisp_Object fullscreen;
+
+  /* Make sure we redisplay all windows in this frame.  */
+  fset_redisplay (f);
+
+  /* Recalculate tab bar and frame text sizes.  */
+  FRAME_TAB_BAR_HEIGHT (f) = height;
+  FRAME_TAB_BAR_LINES (f) = lines;
+  /* Store the `tab-bar-lines' and `height' frame parameters.  */
+  store_frame_param (f, Qtab_bar_lines, make_fixnum (lines));
+  store_frame_param (f, Qheight, make_fixnum (FRAME_LINES (f)));
+
+  /* We also have to make sure that the internal border at the top of
+     the frame, below the menu bar or tab bar, is redrawn when the
+     tab bar disappears.  This is so because the internal border is
+     below the tab bar if one is displayed, but is below the menu bar
+     if there isn't a tab bar.  The tab bar draws into the area
+     below the menu bar.  */
+  if (FRAME_X_WINDOW (f) && FRAME_TAB_BAR_HEIGHT (f) == 0)
+    {
+      clear_frame (f);
+      clear_current_matrices (f);
+    }
+
+  if ((height < old_height) && WINDOWP (f->tab_bar_window))
+    clear_glyph_matrix (XWINDOW (f->tab_bar_window)->current_matrix);
+
+  /* Recalculate tabbar height.  */
+  f->n_tab_bar_rows = 0;
+  if (old_height == 0
+      && (!f->after_make_frame
+         || NILP (frame_inhibit_implied_resize)
+         || (CONSP (frame_inhibit_implied_resize)
+             && NILP (Fmemq (Qtab_bar_lines, frame_inhibit_implied_resize)))))
+    f->tab_bar_redisplayed = f->tab_bar_resized = false;
+
+  adjust_frame_size (f, -1, -1,
+                    ((!f->tab_bar_resized
+                      && (NILP (fullscreen =
+                                get_frame_param (f, Qfullscreen))
+                          || EQ (fullscreen, Qfullwidth))) ? 1
+                     : (old_height == 0 || height == 0) ? 2
+                     : 4),
+                    false, Qtab_bar_lines);
+
+  f->tab_bar_resized = f->tab_bar_redisplayed;
+
+  /* adjust_frame_size might not have done anything, garbage frame
+     here.  */
+  adjust_frame_glyphs (f);
+  SET_FRAME_GARBAGED (f);
+  if (FRAME_X_WINDOW (f))
+    pgtk_clear_under_internal_border (f);
+}
+
 /* Set the pixel height of the tool bar of frame F to HEIGHT.  */
 static void
 x_change_tool_bar_height (struct frame *f, int height)
@@ -812,6 +899,7 @@ frame_parm_handler pgtk_frame_parm_handlers[] =
   gui_set_vertical_scroll_bars, /* generic OK */
   gui_set_horizontal_scroll_bars, /* generic OK */
   gui_set_visibility, /* generic OK */
+  x_set_tab_bar_lines,
   x_set_tool_bar_lines,
   pgtk_set_scroll_bar_foreground,
   pgtk_set_scroll_bar_background,
@@ -1277,6 +1365,10 @@ This function is an internal primitive--use `make-frame' 
instead.  */)
                       NILP (Vmenu_bar_mode)
                       ? make_fixnum (0) : make_fixnum (1),
                       NULL, NULL, RES_TYPE_NUMBER);
+  gui_default_parameter (f, parms, Qtab_bar_lines,
+                         NILP (Vtab_bar_mode)
+                         ? make_fixnum (0) : make_fixnum (1),
+                         NULL, NULL, RES_TYPE_NUMBER);
   gui_default_parameter (f, parms, Qtool_bar_lines,
                       NILP (Vtool_bar_mode)
                       ? make_fixnum (0) : make_fixnum (1),
@@ -1296,7 +1388,7 @@ This function is an internal primitive--use `make-frame' 
instead.  */)
                        RES_TYPE_BOOLEAN);
 
   /* Compute the size of the X window.  */
-  window_prompting = gui_figure_window_size (f, parms, true, &x_width, 
&x_height);
+  window_prompting = gui_figure_window_size (f, parms, true, true, &x_width, 
&x_height);
 
   tem = gui_display_get_arg (dpyinfo, parms, Qunsplittable, 0, 0, 
RES_TYPE_BOOLEAN);
   f->no_split = minibuffer_only || EQ (tem, Qt);
@@ -2568,11 +2660,18 @@ frame_geometry (Lisp_Object frame, Lisp_Object 
attribute)
   int native_right = f->left_pos + outer_width - border;
   int native_bottom = f->top_pos + outer_height - border;
   int internal_border_width = FRAME_INTERNAL_BORDER_WIDTH (f);
+  int tab_bar_height = 0, tab_bar_width = 0;
   int tool_bar_height = FRAME_TOOLBAR_HEIGHT (f);
   int tool_bar_width = (tool_bar_height
                        ? outer_width - 2 * internal_border_width
                        : 0);
 
+  tab_bar_height = FRAME_TAB_BAR_HEIGHT (f);
+  tab_bar_width = (tab_bar_height
+                   ? native_width - 2 * internal_border_width
+                   : 0);
+  // inner_top += tab_bar_height;
+
   /* Construct list.  */
   if (EQ (attribute, Qouter_edges))
     return list4 (make_fixnum (f->left_pos), make_fixnum (f->top_pos),
@@ -2604,6 +2703,9 @@ frame_geometry (Lisp_Object frame, Lisp_Object attribute)
                   Fcons (make_fixnum (0), make_fixnum (title_height))),
            Fcons (Qmenu_bar_external, Qnil),
            Fcons (Qmenu_bar_size, Fcons (make_fixnum (0), make_fixnum (0))),
+           Fcons (Qtab_bar_size,
+                  Fcons (make_fixnum (tab_bar_width),
+                         make_fixnum (tab_bar_height))),
            Fcons (Qtool_bar_external,
                   FRAME_EXTERNAL_TOOL_BAR (f) ? Qt : Qnil),
            Fcons (Qtool_bar_position, FRAME_TOOL_BAR_POSITION (f)),
diff --git a/src/pgtkterm.c b/src/pgtkterm.c
index 92f1409..7c908a3 100644
--- a/src/pgtkterm.c
+++ b/src/pgtkterm.c
@@ -1821,7 +1821,11 @@ x_draw_image_relief (struct glyph_string *s)
   if (s->hl == DRAW_IMAGE_SUNKEN
       || s->hl == DRAW_IMAGE_RAISED)
     {
-      thick = tool_bar_button_relief >= 0 ? tool_bar_button_relief : 
DEFAULT_TOOL_BAR_BUTTON_RELIEF;
+      thick = (tab_bar_button_relief < 0
+              ? DEFAULT_TAB_BAR_BUTTON_RELIEF
+              : (tool_bar_button_relief < 0
+                 ? DEFAULT_TOOL_BAR_BUTTON_RELIEF
+                 : min (tool_bar_button_relief, 1000000)));
       raised_p = s->hl == DRAW_IMAGE_RAISED;
     }
   else
@@ -1834,6 +1838,19 @@ x_draw_image_relief (struct glyph_string *s)
   y1 = y + s->slice.height - 1;
 
   extra_x = extra_y = 0;
+  if (s->face->id == TAB_BAR_FACE_ID)
+    {
+      if (CONSP (Vtab_bar_button_margin)
+         && FIXNUMP (XCAR (Vtab_bar_button_margin))
+         && FIXNUMP (XCDR (Vtab_bar_button_margin)))
+       {
+         extra_x = XFIXNUM (XCAR (Vtab_bar_button_margin));
+         extra_y = XFIXNUM (XCDR (Vtab_bar_button_margin));
+       }
+      else if (FIXNUMP (Vtab_bar_button_margin))
+       extra_x = extra_y = XFIXNUM (Vtab_bar_button_margin);
+    }
+
   if (s->face->id == TOOL_BAR_FACE_ID)
     {
       if (CONSP (Vtool_bar_button_margin)
@@ -4554,6 +4571,7 @@ pgtk_create_terminal (struct pgtk_display_info *dpyinfo)
   terminal->menu_show_hook = pgtk_menu_show;
   terminal->activate_menubar_hook = pgtk_activate_menubar;
   terminal->popup_dialog_hook = pgtk_popup_dialog;
+  terminal->change_tab_bar_height_hook = x_change_tab_bar_height;
   terminal->set_vertical_scroll_bar_hook = pgtk_set_vertical_scroll_bar;
   terminal->set_horizontal_scroll_bar_hook = pgtk_set_horizontal_scroll_bar;
   terminal->condemn_scroll_bars_hook = pgtk_condemn_scroll_bars;
@@ -5556,7 +5574,7 @@ motion_notify_event(GtkWidget *widget, GdkEvent *event, 
gpointer *user_data)
        {
          static Lisp_Object last_mouse_window;
          Lisp_Object window = window_from_coordinates
-           (f, event->motion.x, event->motion.y, 0, false);
+           (f, event->motion.x, event->motion.y, 0, false, false);
 
          /* A window will be autoselected only when it is not
             selected now and the last mouse movement event was
@@ -5676,6 +5694,7 @@ button_event(GtkWidget *widget, GdkEvent *event, gpointer 
*user_data)
 
   /* If we decide we want to generate an event to be seen
      by the rest of Emacs, we put it here.  */
+  bool tab_bar_p = false;
   bool tool_bar_p = false;
 
   EVENT_INIT (inev.ie);
@@ -5725,9 +5744,30 @@ button_event(GtkWidget *widget, GdkEvent *event, 
gpointer *user_data)
 
   if (f && xg_event_is_for_scrollbar (f, event))
     f = 0;
+
+  if (f)
+    {
+      /* Is this in the tab-bar?  */
+      if (WINDOWP (f->tab_bar_window)
+         && WINDOW_TOTAL_LINES (XWINDOW (f->tab_bar_window)))
+       {
+         Lisp_Object window;
+         int x = event->button.x;
+         int y = event->button.y;
+
+         window = window_from_coordinates (f, x, y, 0, true, true);
+         tab_bar_p = EQ (window, f->tab_bar_window);
+
+         if (tab_bar_p && event->button.button < 4)
+           handle_tab_bar_click
+             (f, x, y, event->type == GDK_BUTTON_PRESS,
+              pgtk_gtk_to_emacs_modifiers (dpyinfo, event->button.state));
+       }
+    }
+
   if (f)
     {
-      if (!tool_bar_p)
+      if (!tab_bar_p && !tool_bar_p)
        {
          if (ignore_next_mouse_click_timeout)
            {
diff --git a/src/pgtkterm.h b/src/pgtkterm.h
index 8caf31f..a2ba627 100644
--- a/src/pgtkterm.h
+++ b/src/pgtkterm.h
@@ -600,4 +600,6 @@ extern Lisp_Object x_get_focus_frame (struct frame *frame);
 
 extern void pgtk_frame_rehighlight (struct pgtk_display_info *dpyinfo);
 
+extern void x_change_tab_bar_height (struct frame *, int);
+
 #endif /* HAVE_PGTK */
diff --git a/src/window.h b/src/window.h
index 167d1be..95cfcf3 100644
--- a/src/window.h
+++ b/src/window.h
@@ -756,7 +756,7 @@ wset_next_buffers (struct window *w, Lisp_Object val)
 #endif
 
 /* True if W is a tab bar window.  */
-#if defined (HAVE_WINDOW_SYSTEM)
+#if defined (HAVE_WINDOW_SYSTEM) && !defined(HAVE_PGTK)
 # define WINDOW_TAB_BAR_P(W) \
    (WINDOWP (WINDOW_XFRAME (W)->tab_bar_window) \
     && (W) == XWINDOW (WINDOW_XFRAME (W)->tab_bar_window))



reply via email to

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