Blame src/terminal-notebook.c

Packit Service 3bdf47
/*
Packit Service 3bdf47
 * Copyright © 2001 Havoc Pennington
Packit Service 3bdf47
 * Copyright © 2002 Red Hat, Inc.
Packit Service 3bdf47
 * Copyright © 2008, 2010, 2011, 2012 Christian Persch
Packit Service 3bdf47
 *
Packit Service 3bdf47
 * This program is free software: you can redistribute it and/or modify
Packit Service 3bdf47
 * it under the terms of the GNU General Public License as published by
Packit Service 3bdf47
 * the Free Software Foundation, either version 3 of the License, or
Packit Service 3bdf47
 * (at your option) any later version.
Packit Service 3bdf47
 *
Packit Service 3bdf47
 * This program is distributed in the hope that it will be useful,
Packit Service 3bdf47
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service 3bdf47
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit Service 3bdf47
 * GNU General Public License for more details.
Packit Service 3bdf47
 *
Packit Service 3bdf47
 * You should have received a copy of the GNU General Public License
Packit Service 3bdf47
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
Packit Service 3bdf47
 */
Packit Service 3bdf47
Packit Service 3bdf47
#include <config.h>
Packit Service 3bdf47
Packit Service 3bdf47
#include "terminal-notebook.h"
Packit Service 3bdf47
Packit Service 3bdf47
#include <gtk/gtk.h>
Packit Service 3bdf47
Packit Service 3bdf47
#include "terminal-debug.h"
Packit Service 3bdf47
#include "terminal-app.h"
Packit Service 3bdf47
#include "terminal-intl.h"
Packit Service 3bdf47
#include "terminal-mdi-container.h"
Packit Service 3bdf47
#include "terminal-screen-container.h"
Packit Service 3bdf47
#include "terminal-tab-label.h"
Packit Service 3bdf47
#include "terminal-schemas.h"
Packit Service 3bdf47
#include "terminal-libgsystem.h"
Packit Service 3bdf47
Packit Service 3bdf47
#define TERMINAL_NOTEBOOK_GET_PRIVATE(notebook)(G_TYPE_INSTANCE_GET_PRIVATE ((notebook), TERMINAL_TYPE_NOTEBOOK, TerminalNotebookPrivate))
Packit Service 3bdf47
Packit Service 3bdf47
struct _TerminalNotebookPrivate
Packit Service 3bdf47
{
Packit Service 3bdf47
  TerminalScreen *active_screen;
Packit Service 3bdf47
  GtkPolicyType policy;
Packit Service 3bdf47
};
Packit Service 3bdf47
Packit Service 3bdf47
enum
Packit Service 3bdf47
{
Packit Service 3bdf47
  PROP_0,
Packit Service 3bdf47
  PROP_ACTIVE_SCREEN,
Packit Service 3bdf47
  PROP_TAB_POLICY
Packit Service 3bdf47
};
Packit Service 3bdf47
Packit Service 3bdf47
#define ACTION_AREA_BORDER_WIDTH (2)
Packit Service 3bdf47
#define ACTION_BUTTON_SPACING (6)
Packit Service 3bdf47
Packit Service 3bdf47
/* helper functions */
Packit Service 3bdf47
Packit Service 3bdf47
static void
Packit Service 3bdf47
update_tab_visibility (TerminalNotebook *notebook,
Packit Service 3bdf47
                       int change)
Packit Service 3bdf47
{
Packit Service 3bdf47
  TerminalNotebookPrivate *priv = notebook->priv;
Packit Service 3bdf47
  GtkNotebook *gtk_notebook = GTK_NOTEBOOK (notebook);
Packit Service 3bdf47
  int new_n_pages;
Packit Service 3bdf47
  gboolean show_tabs;
Packit Service 3bdf47
Packit Service 3bdf47
  if (gtk_widget_in_destruction (GTK_WIDGET (notebook)))
Packit Service 3bdf47
    return;
Packit Service 3bdf47
Packit Service 3bdf47
  new_n_pages = gtk_notebook_get_n_pages (gtk_notebook) + change;
Packit Service 3bdf47
  /* Don't do anything if we're going to have zero pages (and thus close the window) */
Packit Service 3bdf47
  if (new_n_pages == 0)
Packit Service 3bdf47
    return;
Packit Service 3bdf47
Packit Service 3bdf47
  switch (priv->policy) {
Packit Service 3bdf47
  case GTK_POLICY_ALWAYS:
Packit Service 3bdf47
    show_tabs = TRUE;
Packit Service 3bdf47
    break;
Packit Service 3bdf47
  case GTK_POLICY_AUTOMATIC:
Packit Service 3bdf47
    show_tabs = new_n_pages > 1;
Packit Service 3bdf47
    break;
Packit Service 3bdf47
  case GTK_POLICY_NEVER:
Packit Service 3bdf47
#if GTK_CHECK_VERSION (3, 16, 0)
Packit Service 3bdf47
  case GTK_POLICY_EXTERNAL:
Packit Service 3bdf47
#endif
Packit Service 3bdf47
  default:
Packit Service 3bdf47
    show_tabs = FALSE;
Packit Service 3bdf47
    break;
Packit Service 3bdf47
  }
Packit Service 3bdf47
Packit Service 3bdf47
  gtk_notebook_set_show_tabs (gtk_notebook, show_tabs);
Packit Service 3bdf47
}
Packit Service 3bdf47
Packit Service 3bdf47
static void
Packit Service 3bdf47
close_button_clicked_cb (TerminalTabLabel *tab_label,
Packit Service 3bdf47
                         gpointer user_data)
Packit Service 3bdf47
{
Packit Service 3bdf47
  TerminalScreen *screen;
Packit Service 3bdf47
  TerminalNotebook *notebook;
Packit Service 3bdf47
Packit Service 3bdf47
  screen = terminal_tab_label_get_screen (tab_label);
Packit Service 3bdf47
Packit Service 3bdf47
  /* notebook is not passed as user_data because it can change during DND
Packit Service 3bdf47
   * and the close button is not notified about that, see bug 731998.
Packit Service 3bdf47
   */
Packit Service 3bdf47
  notebook = TERMINAL_NOTEBOOK (gtk_widget_get_ancestor (GTK_WIDGET (screen),
Packit Service 3bdf47
                                                         TERMINAL_TYPE_NOTEBOOK));
Packit Service 3bdf47
Packit Service 3bdf47
  if (notebook != NULL)
Packit Service 3bdf47
    g_signal_emit_by_name (notebook, "screen-close-request", screen);
Packit Service 3bdf47
}
Packit Service 3bdf47
Packit Service 3bdf47
Packit Service 3bdf47
static void
Packit Service 3bdf47
remove_reorder_bindings (GtkBindingSet    *binding_set,
Packit Service 3bdf47
                         guint             keysym)
Packit Service 3bdf47
{
Packit Service 3bdf47
  guint keypad_keysym = keysym - GDK_KEY_Left + GDK_KEY_KP_Left;
Packit Service 3bdf47
  gtk_binding_entry_skip (binding_set, keysym, GDK_MOD1_MASK);
Packit Service 3bdf47
  gtk_binding_entry_skip (binding_set, keypad_keysym, GDK_MOD1_MASK);
Packit Service 3bdf47
}
Packit Service 3bdf47
Packit Service 3bdf47
/* TerminalMdiContainer impl */
Packit Service 3bdf47
Packit Service 3bdf47
static void
Packit Service 3bdf47
terminal_notebook_add_screen (TerminalMdiContainer *container,
Packit Service 3bdf47
                              TerminalScreen *screen)
Packit Service 3bdf47
{
Packit Service 3bdf47
  TerminalNotebook *notebook = TERMINAL_NOTEBOOK (container);
Packit Service 3bdf47
  GtkNotebook *gtk_notebook = GTK_NOTEBOOK (notebook);
Packit Service 3bdf47
  GtkWidget *screen_container, *tab_label;
Packit Service 3bdf47
  const int position = -1;
Packit Service 3bdf47
Packit Service 3bdf47
  g_warn_if_fail (gtk_widget_get_parent (GTK_WIDGET (screen)) == NULL);
Packit Service 3bdf47
Packit Service 3bdf47
  screen_container = terminal_screen_container_new (screen);
Packit Service 3bdf47
  gtk_widget_show (screen_container);
Packit Service 3bdf47
Packit Service 3bdf47
  update_tab_visibility (notebook, +1);
Packit Service 3bdf47
Packit Service 3bdf47
  tab_label = terminal_tab_label_new (screen);
Packit Service 3bdf47
  g_signal_connect (tab_label, "close-button-clicked",
Packit Service 3bdf47
                    G_CALLBACK (close_button_clicked_cb), NULL);
Packit Service 3bdf47
Packit Service 3bdf47
  gtk_notebook_insert_page (gtk_notebook,
Packit Service 3bdf47
                            screen_container,
Packit Service 3bdf47
                            tab_label,
Packit Service 3bdf47
                            position);
Packit Service 3bdf47
  gtk_container_child_set (GTK_CONTAINER (notebook),
Packit Service 3bdf47
                           screen_container,
Packit Service 3bdf47
                           "tab-expand", TRUE,
Packit Service 3bdf47
                           "tab-fill", TRUE,
Packit Service 3bdf47
                           NULL);
Packit Service 3bdf47
  gtk_notebook_set_tab_reorderable (gtk_notebook, screen_container, TRUE);
Packit Service 3bdf47
#if 0
Packit Service 3bdf47
  gtk_notebook_set_tab_detachable (gtk_notebook, screen_container, TRUE);
Packit Service 3bdf47
#endif
Packit Service 3bdf47
}
Packit Service 3bdf47
Packit Service 3bdf47
static void
Packit Service 3bdf47
terminal_notebook_remove_screen (TerminalMdiContainer *container,
Packit Service 3bdf47
                                 TerminalScreen *screen)
Packit Service 3bdf47
{
Packit Service 3bdf47
  TerminalNotebook *notebook = TERMINAL_NOTEBOOK (container);
Packit Service 3bdf47
  TerminalScreenContainer *screen_container;
Packit Service 3bdf47
Packit Service 3bdf47
  g_warn_if_fail (gtk_widget_is_ancestor (GTK_WIDGET (screen), GTK_WIDGET (notebook)));
Packit Service 3bdf47
Packit Service 3bdf47
  update_tab_visibility (notebook, -1);
Packit Service 3bdf47
Packit Service 3bdf47
  screen_container = terminal_screen_container_get_from_screen (screen);
Packit Service 3bdf47
  gtk_container_remove (GTK_CONTAINER (notebook),
Packit Service 3bdf47
                        GTK_WIDGET (screen_container));
Packit Service 3bdf47
}
Packit Service 3bdf47
Packit Service 3bdf47
static TerminalScreen *
Packit Service 3bdf47
terminal_notebook_get_active_screen (TerminalMdiContainer *container)
Packit Service 3bdf47
{
Packit Service 3bdf47
  TerminalNotebook *notebook = TERMINAL_NOTEBOOK (container);
Packit Service 3bdf47
  GtkNotebook *gtk_notebook = GTK_NOTEBOOK (notebook);
Packit Service 3bdf47
  GtkWidget *widget;
Packit Service 3bdf47
Packit Service 3bdf47
  widget = gtk_notebook_get_nth_page (gtk_notebook, gtk_notebook_get_current_page (gtk_notebook));
Packit Service 3bdf47
  return terminal_screen_container_get_screen (TERMINAL_SCREEN_CONTAINER (widget));
Packit Service 3bdf47
}
Packit Service 3bdf47
Packit Service 3bdf47
static void
Packit Service 3bdf47
terminal_notebook_set_active_screen (TerminalMdiContainer *container,
Packit Service 3bdf47
                                     TerminalScreen *screen)
Packit Service 3bdf47
{
Packit Service 3bdf47
  TerminalNotebook *notebook = TERMINAL_NOTEBOOK (container);
Packit Service 3bdf47
  GtkNotebook *gtk_notebook = GTK_NOTEBOOK (notebook);
Packit Service 3bdf47
  TerminalScreenContainer *screen_container;
Packit Service 3bdf47
  GtkWidget *widget;
Packit Service 3bdf47
Packit Service 3bdf47
  screen_container = terminal_screen_container_get_from_screen (screen);
Packit Service 3bdf47
  widget = GTK_WIDGET (screen_container);
Packit Service 3bdf47
Packit Service 3bdf47
  gtk_notebook_set_current_page (gtk_notebook,
Packit Service 3bdf47
                                 gtk_notebook_page_num (gtk_notebook, widget));
Packit Service 3bdf47
}
Packit Service 3bdf47
Packit Service 3bdf47
static GList *
Packit Service 3bdf47
terminal_notebook_list_screen_containers (TerminalMdiContainer *container)
Packit Service 3bdf47
{
Packit Service 3bdf47
  /* We are trusting that GtkNotebook will return pages in order */
Packit Service 3bdf47
  return gtk_container_get_children (GTK_CONTAINER (container));
Packit Service 3bdf47
}
Packit Service 3bdf47
Packit Service 3bdf47
static GList *
Packit Service 3bdf47
terminal_notebook_list_screens (TerminalMdiContainer *container)
Packit Service 3bdf47
{
Packit Service 3bdf47
  GList *list, *l;
Packit Service 3bdf47
Packit Service 3bdf47
  list = terminal_notebook_list_screen_containers (container);
Packit Service 3bdf47
  for (l = list; l != NULL; l = l->next)
Packit Service 3bdf47
    l->data = terminal_screen_container_get_screen ((TerminalScreenContainer *) l->data);
Packit Service 3bdf47
Packit Service 3bdf47
  return list;
Packit Service 3bdf47
}
Packit Service 3bdf47
Packit Service 3bdf47
static int
Packit Service 3bdf47
terminal_notebook_get_n_screens (TerminalMdiContainer *container)
Packit Service 3bdf47
{
Packit Service 3bdf47
  return gtk_notebook_get_n_pages (GTK_NOTEBOOK (container));
Packit Service 3bdf47
}
Packit Service 3bdf47
Packit Service 3bdf47
static int
Packit Service 3bdf47
terminal_notebook_get_active_screen_num (TerminalMdiContainer *container)
Packit Service 3bdf47
{
Packit Service 3bdf47
  return gtk_notebook_get_current_page (GTK_NOTEBOOK (container));
Packit Service 3bdf47
}
Packit Service 3bdf47
Packit Service 3bdf47
static void
Packit Service 3bdf47
terminal_notebook_set_active_screen_num (TerminalMdiContainer *container,
Packit Service 3bdf47
                                         int position)
Packit Service 3bdf47
{
Packit Service 3bdf47
  GtkNotebook *gtk_notebook = GTK_NOTEBOOK (container);
Packit Service 3bdf47
Packit Service 3bdf47
  gtk_notebook_set_current_page (gtk_notebook, position);
Packit Service 3bdf47
}
Packit Service 3bdf47
Packit Service 3bdf47
static void
Packit Service 3bdf47
terminal_notebook_reorder_screen (TerminalMdiContainer *container,
Packit Service 3bdf47
                                  TerminalScreen *screen,
Packit Service 3bdf47
                                  int new_position)
Packit Service 3bdf47
{
Packit Service 3bdf47
  GtkNotebook *notebook = GTK_NOTEBOOK (container);
Packit Service 3bdf47
  GtkWidget *child;
Packit Service 3bdf47
  int n, pos;
Packit Service 3bdf47
Packit Service 3bdf47
  g_return_if_fail (new_position == 1 || new_position == -1);
Packit Service 3bdf47
Packit Service 3bdf47
  child = GTK_WIDGET (terminal_screen_container_get_from_screen (screen));
Packit Service 3bdf47
  n = gtk_notebook_get_n_pages (notebook);
Packit Service 3bdf47
  pos = gtk_notebook_page_num (notebook, child);
Packit Service 3bdf47
Packit Service 3bdf47
  pos += new_position;
Packit Service 3bdf47
  gtk_notebook_reorder_child (notebook, child,
Packit Service 3bdf47
                              pos < 0 ? n - 1 : pos < n ? pos : 0);
Packit Service 3bdf47
}
Packit Service 3bdf47
Packit Service 3bdf47
static void
Packit Service 3bdf47
terminal_notebook_mdi_iface_init (TerminalMdiContainerInterface *iface)
Packit Service 3bdf47
{
Packit Service 3bdf47
  iface->add_screen = terminal_notebook_add_screen;
Packit Service 3bdf47
  iface->remove_screen = terminal_notebook_remove_screen;
Packit Service 3bdf47
  iface->get_active_screen = terminal_notebook_get_active_screen;
Packit Service 3bdf47
  iface->set_active_screen = terminal_notebook_set_active_screen;
Packit Service 3bdf47
  iface->list_screens = terminal_notebook_list_screens;
Packit Service 3bdf47
  iface->list_screen_containers = terminal_notebook_list_screen_containers;
Packit Service 3bdf47
  iface->get_n_screens = terminal_notebook_get_n_screens;
Packit Service 3bdf47
  iface->get_active_screen_num = terminal_notebook_get_active_screen_num;
Packit Service 3bdf47
  iface->set_active_screen_num = terminal_notebook_set_active_screen_num;
Packit Service 3bdf47
  iface->reorder_screen = terminal_notebook_reorder_screen;
Packit Service 3bdf47
}
Packit Service 3bdf47
Packit Service 3bdf47
G_DEFINE_TYPE_WITH_CODE (TerminalNotebook, terminal_notebook, GTK_TYPE_NOTEBOOK,
Packit Service 3bdf47
                         G_IMPLEMENT_INTERFACE (TERMINAL_TYPE_MDI_CONTAINER, terminal_notebook_mdi_iface_init))
Packit Service 3bdf47
Packit Service 3bdf47
/* GtkNotebookClass impl */
Packit Service 3bdf47
Packit Service 3bdf47
static void
Packit Service 3bdf47
terminal_notebook_switch_page (GtkNotebook     *gtk_notebook,
Packit Service 3bdf47
                               GtkWidget       *child,
Packit Service 3bdf47
                               guint            page_num)
Packit Service 3bdf47
{
Packit Service 3bdf47
  TerminalNotebook *notebook = TERMINAL_NOTEBOOK (gtk_notebook);
Packit Service 3bdf47
  TerminalNotebookPrivate *priv = notebook->priv;
Packit Service 3bdf47
  TerminalScreen *screen, *old_active_screen;
Packit Service 3bdf47
Packit Service 3bdf47
  GTK_NOTEBOOK_CLASS (terminal_notebook_parent_class)->switch_page (gtk_notebook, child, page_num);
Packit Service 3bdf47
Packit Service 3bdf47
  screen = terminal_screen_container_get_screen (TERMINAL_SCREEN_CONTAINER (child));
Packit Service 3bdf47
Packit Service 3bdf47
  old_active_screen = priv->active_screen;
Packit Service 3bdf47
  if (screen == old_active_screen)
Packit Service 3bdf47
    return;
Packit Service 3bdf47
Packit Service 3bdf47
  /* Workaround to remove gtknotebook's feature of computing its size based on
Packit Service 3bdf47
   * all pages. When the widget is hidden, its size will not be taken into
Packit Service 3bdf47
   * account.
Packit Service 3bdf47
   * FIXME!
Packit Service 3bdf47
   */
Packit Service 3bdf47
//   if (old_active_screen)
Packit Service 3bdf47
//     gtk_widget_hide (GTK_WIDGET (terminal_screen_container_get_from_screen (old_active_screen)));
Packit Service 3bdf47
  /* Make sure that the widget is no longer hidden due to the workaround */
Packit Service 3bdf47
//   if (child)
Packit Service 3bdf47
//     gtk_widget_show (child);
Packit Service 3bdf47
  if (old_active_screen)
Packit Service 3bdf47
    gtk_widget_hide (GTK_WIDGET (old_active_screen));
Packit Service 3bdf47
  if (screen)
Packit Service 3bdf47
    gtk_widget_show (GTK_WIDGET (screen));
Packit Service 3bdf47
Packit Service 3bdf47
  priv->active_screen = screen;
Packit Service 3bdf47
Packit Service 3bdf47
  g_signal_emit_by_name (notebook, "screen-switched", old_active_screen, screen);
Packit Service 3bdf47
  g_object_notify (G_OBJECT (notebook), "active-screen");
Packit Service 3bdf47
}
Packit Service 3bdf47
Packit Service 3bdf47
static void
Packit Service 3bdf47
terminal_notebook_page_added (GtkNotebook     *gtk_notebook,
Packit Service 3bdf47
                              GtkWidget       *child,
Packit Service 3bdf47
                              guint            page_num)
Packit Service 3bdf47
{
Packit Service 3bdf47
  TerminalNotebook *notebook = TERMINAL_NOTEBOOK (gtk_notebook);
Packit Service 3bdf47
  void (* page_added) (GtkNotebook *, GtkWidget *, guint) =
Packit Service 3bdf47
    GTK_NOTEBOOK_CLASS (terminal_notebook_parent_class)->page_added;
Packit Service 3bdf47
Packit Service 3bdf47
  if (page_added)
Packit Service 3bdf47
    page_added (gtk_notebook, child, page_num);
Packit Service 3bdf47
Packit Service 3bdf47
  update_tab_visibility (notebook, 0);
Packit Service 3bdf47
  g_signal_emit_by_name (gtk_notebook, "screen-added",
Packit Service 3bdf47
                         terminal_screen_container_get_screen (TERMINAL_SCREEN_CONTAINER (child)));
Packit Service 3bdf47
}
Packit Service 3bdf47
Packit Service 3bdf47
static void
Packit Service 3bdf47
terminal_notebook_page_removed (GtkNotebook     *gtk_notebook,
Packit Service 3bdf47
                                GtkWidget       *child,
Packit Service 3bdf47
                                guint            page_num)
Packit Service 3bdf47
{
Packit Service 3bdf47
  TerminalNotebook *notebook = TERMINAL_NOTEBOOK (gtk_notebook);
Packit Service 3bdf47
  void (* page_removed) (GtkNotebook *, GtkWidget *, guint) =
Packit Service 3bdf47
    GTK_NOTEBOOK_CLASS (terminal_notebook_parent_class)->page_removed;
Packit Service 3bdf47
Packit Service 3bdf47
  if (page_removed)
Packit Service 3bdf47
    page_removed (gtk_notebook, child, page_num);
Packit Service 3bdf47
Packit Service 3bdf47
  update_tab_visibility (notebook, 0);
Packit Service 3bdf47
  g_signal_emit_by_name (gtk_notebook, "screen-removed",
Packit Service 3bdf47
                         terminal_screen_container_get_screen (TERMINAL_SCREEN_CONTAINER (child)));
Packit Service 3bdf47
}
Packit Service 3bdf47
Packit Service 3bdf47
static void
Packit Service 3bdf47
terminal_notebook_page_reordered (GtkNotebook     *notebook,
Packit Service 3bdf47
                                  GtkWidget       *child,
Packit Service 3bdf47
                                  guint            page_num)
Packit Service 3bdf47
{
Packit Service 3bdf47
  void (* page_reordered) (GtkNotebook *, GtkWidget *, guint) =
Packit Service 3bdf47
    GTK_NOTEBOOK_CLASS (terminal_notebook_parent_class)->page_reordered;
Packit Service 3bdf47
Packit Service 3bdf47
  if (page_reordered)
Packit Service 3bdf47
    page_reordered (notebook, child, page_num);
Packit Service 3bdf47
Packit Service 3bdf47
  g_signal_emit_by_name (notebook, "screens-reordered");
Packit Service 3bdf47
}
Packit Service 3bdf47
Packit Service 3bdf47
static GtkNotebook *
Packit Service 3bdf47
terminal_notebook_create_window (GtkNotebook       *notebook,
Packit Service 3bdf47
                                 GtkWidget         *page,
Packit Service 3bdf47
                                 gint               x,
Packit Service 3bdf47
                                 gint               y)
Packit Service 3bdf47
{
Packit Service 3bdf47
  return GTK_NOTEBOOK_CLASS (terminal_notebook_parent_class)->create_window (notebook, page, x, y);
Packit Service 3bdf47
}
Packit Service 3bdf47
Packit Service 3bdf47
/* GtkWidgetClass impl */
Packit Service 3bdf47
Packit Service 3bdf47
static void
Packit Service 3bdf47
terminal_notebook_grab_focus (GtkWidget *widget)
Packit Service 3bdf47
{
Packit Service 3bdf47
  TerminalScreen *screen;
Packit Service 3bdf47
Packit Service 3bdf47
  screen = terminal_mdi_container_get_active_screen (TERMINAL_MDI_CONTAINER (widget));
Packit Service 3bdf47
  gtk_widget_grab_focus (GTK_WIDGET (screen));
Packit Service 3bdf47
}
Packit Service 3bdf47
Packit Service 3bdf47
/* Tab scrolling was removed from GtkNotebook in gtk 3, so reimplement it here */
Packit Service 3bdf47
static gboolean
Packit Service 3bdf47
terminal_notebook_scroll_event (GtkWidget      *widget,
Packit Service 3bdf47
                                GdkEventScroll *event)
Packit Service 3bdf47
{
Packit Service 3bdf47
  GtkNotebook *notebook = GTK_NOTEBOOK (widget);
Packit Service 3bdf47
  gboolean (* scroll_event) (GtkWidget *, GdkEventScroll *) =
Packit Service 3bdf47
    GTK_WIDGET_CLASS (terminal_notebook_parent_class)->scroll_event;
Packit Service 3bdf47
  GtkWidget *child, *event_widget, *action_widget;
Packit Service 3bdf47
Packit Service 3bdf47
  if ((event->state & gtk_accelerator_get_default_mod_mask ()) != 0)
Packit Service 3bdf47
    goto chain_up;
Packit Service 3bdf47
Packit Service 3bdf47
  child = gtk_notebook_get_nth_page (notebook, gtk_notebook_get_current_page (notebook));
Packit Service 3bdf47
  if (child == NULL)
Packit Service 3bdf47
    goto chain_up;
Packit Service 3bdf47
Packit Service 3bdf47
  event_widget = gtk_get_event_widget ((GdkEvent *) event);
Packit Service 3bdf47
Packit Service 3bdf47
  /* Ignore scroll events from the content of the page */
Packit Service 3bdf47
  if (event_widget == NULL ||
Packit Service 3bdf47
      event_widget == child ||
Packit Service 3bdf47
      gtk_widget_is_ancestor (event_widget, child))
Packit Service 3bdf47
    goto chain_up;
Packit Service 3bdf47
Packit Service 3bdf47
  /* And also from the action widgets */
Packit Service 3bdf47
  action_widget = gtk_notebook_get_action_widget (notebook, GTK_PACK_START);
Packit Service 3bdf47
  if (event_widget == action_widget ||
Packit Service 3bdf47
      (action_widget != NULL && gtk_widget_is_ancestor (event_widget, action_widget)))
Packit Service 3bdf47
    goto chain_up;
Packit Service 3bdf47
  action_widget = gtk_notebook_get_action_widget (notebook, GTK_PACK_END);
Packit Service 3bdf47
  if (event_widget == action_widget ||
Packit Service 3bdf47
      (action_widget != NULL && gtk_widget_is_ancestor (event_widget, action_widget)))
Packit Service 3bdf47
    goto chain_up;
Packit Service 3bdf47
Packit Service 3bdf47
  switch (event->direction) {
Packit Service 3bdf47
    case GDK_SCROLL_RIGHT:
Packit Service 3bdf47
    case GDK_SCROLL_DOWN:
Packit Service 3bdf47
      gtk_notebook_next_page (notebook);
Packit Service 3bdf47
      return TRUE;
Packit Service 3bdf47
    case GDK_SCROLL_LEFT:
Packit Service 3bdf47
    case GDK_SCROLL_UP:
Packit Service 3bdf47
      gtk_notebook_prev_page (notebook);
Packit Service 3bdf47
      return TRUE;
Packit Service 3bdf47
    case GDK_SCROLL_SMOOTH:
Packit Service 3bdf47
      switch (gtk_notebook_get_tab_pos (notebook)) {
Packit Service 3bdf47
        case GTK_POS_LEFT:
Packit Service 3bdf47
        case GTK_POS_RIGHT:
Packit Service 3bdf47
          if (event->delta_y > 0)
Packit Service 3bdf47
            gtk_notebook_next_page (notebook);
Packit Service 3bdf47
          else if (event->delta_y < 0)
Packit Service 3bdf47
            gtk_notebook_prev_page (notebook);
Packit Service 3bdf47
          break;
Packit Service 3bdf47
        case GTK_POS_TOP:
Packit Service 3bdf47
        case GTK_POS_BOTTOM:
Packit Service 3bdf47
          if (event->delta_x > 0)
Packit Service 3bdf47
            gtk_notebook_next_page (notebook);
Packit Service 3bdf47
          else if (event->delta_x < 0)
Packit Service 3bdf47
            gtk_notebook_prev_page (notebook);
Packit Service 3bdf47
          break;
Packit Service 3bdf47
      }
Packit Service 3bdf47
      return TRUE;
Packit Service 3bdf47
  }
Packit Service 3bdf47
Packit Service 3bdf47
chain_up:
Packit Service 3bdf47
  if (scroll_event)
Packit Service 3bdf47
    return scroll_event (widget, event);
Packit Service 3bdf47
Packit Service 3bdf47
  return FALSE;
Packit Service 3bdf47
}
Packit Service 3bdf47
Packit Service 3bdf47
/* GObjectClass impl */
Packit Service 3bdf47
Packit Service 3bdf47
static void
Packit Service 3bdf47
terminal_notebook_init (TerminalNotebook *notebook)
Packit Service 3bdf47
{
Packit Service 3bdf47
  TerminalNotebookPrivate *priv;
Packit Service 3bdf47
Packit Service 3bdf47
  priv = notebook->priv = TERMINAL_NOTEBOOK_GET_PRIVATE (notebook);
Packit Service 3bdf47
Packit Service 3bdf47
  priv->active_screen = NULL;
Packit Service 3bdf47
  priv->policy = GTK_POLICY_AUTOMATIC;
Packit Service 3bdf47
}
Packit Service 3bdf47
Packit Service 3bdf47
static void
Packit Service 3bdf47
terminal_notebook_constructed (GObject *object)
Packit Service 3bdf47
{
Packit Service 3bdf47
  GSettings *settings;
Packit Service 3bdf47
  GtkWidget *widget = GTK_WIDGET (object);
Packit Service 3bdf47
  GtkNotebook *notebook = GTK_NOTEBOOK (object);
Packit Service 3bdf47
Packit Service 3bdf47
  G_OBJECT_CLASS (terminal_notebook_parent_class)->constructed (object);
Packit Service 3bdf47
Packit Service 3bdf47
  settings = terminal_app_get_global_settings (terminal_app_get ());
Packit Service 3bdf47
Packit Service 3bdf47
  update_tab_visibility (TERMINAL_NOTEBOOK (notebook), 0);
Packit Service 3bdf47
  g_settings_bind (settings,
Packit Service 3bdf47
                   TERMINAL_SETTING_TAB_POLICY_KEY,
Packit Service 3bdf47
                   object,
Packit Service 3bdf47
                   "tab-policy",
Packit Service 3bdf47
                   G_SETTINGS_BIND_GET | G_SETTINGS_BIND_NO_SENSITIVITY);
Packit Service 3bdf47
Packit Service 3bdf47
  g_settings_bind (settings,
Packit Service 3bdf47
                   TERMINAL_SETTING_TAB_POSITION_KEY,
Packit Service 3bdf47
                   object,
Packit Service 3bdf47
                   "tab-pos",
Packit Service 3bdf47
                   G_SETTINGS_BIND_GET | G_SETTINGS_BIND_NO_SENSITIVITY);
Packit Service 3bdf47
Packit Service 3bdf47
  gtk_notebook_set_scrollable (notebook, TRUE);
Packit Service 3bdf47
  gtk_notebook_set_show_border (notebook, FALSE);
Packit Service 3bdf47
  gtk_notebook_set_group_name (notebook, I_("gnome-terminal-window"));
Packit Service 3bdf47
Packit Service 3bdf47
  /* Necessary for scroll events */
Packit Service 3bdf47
  gtk_widget_add_events (widget, GDK_SCROLL_MASK);
Packit Service 3bdf47
}
Packit Service 3bdf47
Packit Service 3bdf47
static void
Packit Service 3bdf47
terminal_notebook_get_property (GObject *object,
Packit Service 3bdf47
                                guint prop_id,
Packit Service 3bdf47
                                GValue *value,
Packit Service 3bdf47
                                GParamSpec *pspec)
Packit Service 3bdf47
{
Packit Service 3bdf47
  TerminalMdiContainer *mdi_container = TERMINAL_MDI_CONTAINER (object);
Packit Service 3bdf47
Packit Service 3bdf47
  switch (prop_id) {
Packit Service 3bdf47
    case PROP_ACTIVE_SCREEN:
Packit Service 3bdf47
      g_value_set_object (value, terminal_notebook_get_active_screen (mdi_container));
Packit Service 3bdf47
      break;
Packit Service 3bdf47
    case PROP_TAB_POLICY:
Packit Service 3bdf47
      g_value_set_enum (value, terminal_notebook_get_tab_policy (TERMINAL_NOTEBOOK (mdi_container)));
Packit Service 3bdf47
      break;
Packit Service 3bdf47
    default:
Packit Service 3bdf47
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
Packit Service 3bdf47
      break;
Packit Service 3bdf47
  }
Packit Service 3bdf47
}
Packit Service 3bdf47
Packit Service 3bdf47
static void
Packit Service 3bdf47
terminal_notebook_set_property (GObject *object,
Packit Service 3bdf47
                                guint prop_id,
Packit Service 3bdf47
                                const GValue *value,
Packit Service 3bdf47
                                GParamSpec *pspec)
Packit Service 3bdf47
{
Packit Service 3bdf47
  TerminalMdiContainer *mdi_container = TERMINAL_MDI_CONTAINER (object);
Packit Service 3bdf47
Packit Service 3bdf47
  switch (prop_id) {
Packit Service 3bdf47
    case PROP_ACTIVE_SCREEN:
Packit Service 3bdf47
      terminal_notebook_set_active_screen (mdi_container, g_value_get_object (value));
Packit Service 3bdf47
      break;
Packit Service 3bdf47
    case PROP_TAB_POLICY:
Packit Service 3bdf47
      terminal_notebook_set_tab_policy (TERMINAL_NOTEBOOK (mdi_container), g_value_get_enum (value));
Packit Service 3bdf47
      break;
Packit Service 3bdf47
    default:
Packit Service 3bdf47
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
Packit Service 3bdf47
      break;
Packit Service 3bdf47
  }
Packit Service 3bdf47
}
Packit Service 3bdf47
Packit Service 3bdf47
static void
Packit Service 3bdf47
terminal_notebook_class_init (TerminalNotebookClass *klass)
Packit Service 3bdf47
{
Packit Service 3bdf47
  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
Packit Service 3bdf47
  GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
Packit Service 3bdf47
  GtkNotebookClass *notebook_class = GTK_NOTEBOOK_CLASS (klass);
Packit Service 3bdf47
Packit Service 3bdf47
  g_type_class_add_private (gobject_class, sizeof (TerminalNotebookPrivate));
Packit Service 3bdf47
Packit Service 3bdf47
  gobject_class->constructed = terminal_notebook_constructed;
Packit Service 3bdf47
  gobject_class->get_property = terminal_notebook_get_property;
Packit Service 3bdf47
  gobject_class->set_property = terminal_notebook_set_property;
Packit Service 3bdf47
Packit Service 3bdf47
  g_object_class_override_property (gobject_class, PROP_ACTIVE_SCREEN, "active-screen");
Packit Service 3bdf47
Packit Service 3bdf47
  widget_class->grab_focus = terminal_notebook_grab_focus;
Packit Service 3bdf47
  widget_class->scroll_event = terminal_notebook_scroll_event;
Packit Service 3bdf47
Packit Service 3bdf47
  notebook_class->switch_page = terminal_notebook_switch_page;
Packit Service 3bdf47
  notebook_class->create_window = terminal_notebook_create_window;
Packit Service 3bdf47
  notebook_class->page_added = terminal_notebook_page_added;
Packit Service 3bdf47
  notebook_class->page_removed = terminal_notebook_page_removed;
Packit Service 3bdf47
  notebook_class->page_reordered = terminal_notebook_page_reordered;
Packit Service 3bdf47
Packit Service 3bdf47
  g_object_class_install_property
Packit Service 3bdf47
    (gobject_class,
Packit Service 3bdf47
     PROP_TAB_POLICY,
Packit Service 3bdf47
     g_param_spec_enum ("tab-policy", NULL, NULL,
Packit Service 3bdf47
                        GTK_TYPE_POLICY_TYPE,
Packit Service 3bdf47
                        GTK_POLICY_AUTOMATIC,
Packit Service 3bdf47
                        G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
Packit Service 3bdf47
Packit Service 3bdf47
  /* Remove unwanted and interfering keybindings */
Packit Service 3bdf47
  GtkBindingSet *binding_set = gtk_binding_set_by_class (terminal_notebook_parent_class);
Packit Service 3bdf47
  gtk_binding_entry_skip (binding_set, GDK_KEY_Page_Up, GDK_CONTROL_MASK);
Packit Service 3bdf47
  gtk_binding_entry_skip (binding_set, GDK_KEY_Page_Up, GDK_CONTROL_MASK | GDK_MOD1_MASK);
Packit Service 3bdf47
  gtk_binding_entry_skip (binding_set, GDK_KEY_Page_Down, GDK_CONTROL_MASK);
Packit Service 3bdf47
  gtk_binding_entry_skip (binding_set, GDK_KEY_Page_Down, GDK_CONTROL_MASK | GDK_MOD1_MASK);
Packit Service 3bdf47
  remove_reorder_bindings (binding_set, GDK_KEY_Up);
Packit Service 3bdf47
  remove_reorder_bindings (binding_set, GDK_KEY_Down);
Packit Service 3bdf47
  remove_reorder_bindings (binding_set, GDK_KEY_Left);
Packit Service 3bdf47
  remove_reorder_bindings (binding_set, GDK_KEY_Right);
Packit Service 3bdf47
  remove_reorder_bindings (binding_set, GDK_KEY_Home);
Packit Service 3bdf47
  remove_reorder_bindings (binding_set, GDK_KEY_Home);
Packit Service 3bdf47
  remove_reorder_bindings (binding_set, GDK_KEY_End);
Packit Service 3bdf47
  remove_reorder_bindings (binding_set, GDK_KEY_End);
Packit Service 3bdf47
}
Packit Service 3bdf47
Packit Service 3bdf47
/* public API */
Packit Service 3bdf47
Packit Service 3bdf47
/**
Packit Service 3bdf47
 * terminal_notebook_new:
Packit Service 3bdf47
 *
Packit Service 3bdf47
 * Returns: (transfer full): a new #TerminalNotebook
Packit Service 3bdf47
 */
Packit Service 3bdf47
GtkWidget *
Packit Service 3bdf47
terminal_notebook_new (void)
Packit Service 3bdf47
{
Packit Service 3bdf47
  return g_object_new (TERMINAL_TYPE_NOTEBOOK, NULL);
Packit Service 3bdf47
}
Packit Service 3bdf47
Packit Service 3bdf47
void
Packit Service 3bdf47
terminal_notebook_set_tab_policy (TerminalNotebook *notebook,
Packit Service 3bdf47
                                  GtkPolicyType policy)
Packit Service 3bdf47
{
Packit Service 3bdf47
  TerminalNotebookPrivate *priv = notebook->priv;
Packit Service 3bdf47
Packit Service 3bdf47
  if (priv->policy == policy)
Packit Service 3bdf47
    return;
Packit Service 3bdf47
Packit Service 3bdf47
  priv->policy = policy;
Packit Service 3bdf47
  update_tab_visibility (notebook, 0);
Packit Service 3bdf47
Packit Service 3bdf47
  g_object_notify (G_OBJECT (notebook), "tab-policy");
Packit Service 3bdf47
}
Packit Service 3bdf47
Packit Service 3bdf47
GtkPolicyType
Packit Service 3bdf47
terminal_notebook_get_tab_policy (TerminalNotebook *notebook)
Packit Service 3bdf47
{
Packit Service 3bdf47
  return notebook->priv->policy;
Packit Service 3bdf47
}
Packit Service 3bdf47
Packit Service 3bdf47
GtkWidget *
Packit Service 3bdf47
terminal_notebook_get_action_box (TerminalNotebook *notebook,
Packit Service 3bdf47
                                  GtkPackType pack_type)
Packit Service 3bdf47
{
Packit Service 3bdf47
  GtkNotebook *gtk_notebook;
Packit Service 3bdf47
  GtkWidget *box, *inner_box;
Packit Service 3bdf47
Packit Service 3bdf47
  g_return_val_if_fail (TERMINAL_IS_NOTEBOOK (notebook), NULL);
Packit Service 3bdf47
Packit Service 3bdf47
  gtk_notebook = GTK_NOTEBOOK (notebook);
Packit Service 3bdf47
  box = gtk_notebook_get_action_widget (gtk_notebook, pack_type);
Packit Service 3bdf47
  if (box != NULL) {
Packit Service 3bdf47
    gs_free_list GList *list;
Packit Service 3bdf47
Packit Service 3bdf47
    list = gtk_container_get_children (GTK_CONTAINER (box));
Packit Service 3bdf47
    g_assert (list->data != NULL);
Packit Service 3bdf47
    return list->data;
Packit Service 3bdf47
  }
Packit Service 3bdf47
Packit Service 3bdf47
  /* Create container for the buttons */
Packit Service 3bdf47
  box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
Packit Service 3bdf47
  gtk_container_set_border_width (GTK_CONTAINER (box), ACTION_AREA_BORDER_WIDTH);
Packit Service 3bdf47
Packit Service 3bdf47
  inner_box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, ACTION_BUTTON_SPACING);
Packit Service 3bdf47
  gtk_box_pack_start (GTK_BOX (box), inner_box, TRUE, FALSE, 0);
Packit Service 3bdf47
  gtk_widget_show (inner_box);
Packit Service 3bdf47
Packit Service 3bdf47
  gtk_notebook_set_action_widget (gtk_notebook, box, pack_type);
Packit Service 3bdf47
  gtk_widget_show (box);
Packit Service 3bdf47
Packit Service 3bdf47
  /* FIXME: this appears to be necessary to make the icon buttons contained
Packit Service 3bdf47
   * in the action area render the same way as buttons in the tab labels (e.g.
Packit Service 3bdf47
   * the close button). gtk+ bug?
Packit Service 3bdf47
   */
Packit Service 3bdf47
  G_GNUC_BEGIN_IGNORE_DEPRECATIONS
Packit Service 3bdf47
  gtk_style_context_add_region (gtk_widget_get_style_context (box),
Packit Service 3bdf47
                                GTK_STYLE_REGION_TAB,
Packit Service 3bdf47
                                pack_type == GTK_PACK_START ? GTK_REGION_FIRST : GTK_REGION_LAST);
Packit Service 3bdf47
  G_GNUC_END_IGNORE_DEPRECATIONS
Packit Service 3bdf47
Packit Service 3bdf47
  return inner_box;
Packit Service 3bdf47
}