diff options
| -rw-r--r-- | svte.c | 181 | 
1 files changed, 101 insertions, 80 deletions
| @@ -24,17 +24,17 @@  #include <vte/vte.h>  #include <unistd.h> -static struct { +typedef struct window {    GtkWidget *win;    GtkWidget *notebook;    gchar *title; -} svte; - +} window;  typedef struct term {    GtkWidget *vte;    GtkWidget *label;    GPid *pid; +  struct window *w;  } term;  typedef struct { @@ -62,23 +62,23 @@ typedef struct {  } Settings;  static void quit(); -gboolean event_key(GtkWidget *widget, GdkEventKey *event); +gboolean event_key(GtkWidget *widget, GdkEventKey *event, window *w);  gboolean event_button(GtkWidget *widget, GdkEventButton *button_event); -static void tab_close(); +static void tab_close(VteTerminal *term, struct window *w);  static char* tab_get_cwd(struct term* t); -static void tab_switch(gboolean b); +static void tab_switch(gboolean b, struct window *w);  static void tab_title();  static void tab_geometry_hints(); -static void tab_new(); -static void tab_togglebar(); -static void configure_window(); +static void tab_new(struct window *w); +static void tab_togglebar(struct window *w); +static void new_window();  static void tab_focus(GtkNotebook *notebook, GtkNotebookPage *page, -    guint page_num, gpointer user_data); +    guint page_num, struct window *w);  static void set_window_title(term *t);  static void launch_url(char *url); -static inline term* get_current_term(); -static inline term* get_nth_term(guint page); +static inline term* get_current_term(window *w); +static inline term* get_nth_term(window *w, guint page);  static GQuark term_data_id = 0;  static Settings *config; @@ -99,16 +99,16 @@ static void quit() {  /* return the nth page */ -//#define get_page_term( sakura, page_idx ) (struct term*)g_object_get_qdata(G_OBJECT( gtk_notebook_get_nth_page( (GtkNotebook*)svte.notebook, page_idx ) ), term_data_id); -static inline term* get_nth_term(guint page) { -  return (struct term*)g_object_get_qdata(G_OBJECT(gtk_notebook_get_nth_page((GtkNotebook*)svte.notebook, page) ), term_data_id); +static inline term* get_nth_term(window *w, guint page) { +  return (struct term*)g_object_get_qdata(G_OBJECT(gtk_notebook_get_nth_page((GtkNotebook*)w->notebook, page) ), term_data_id);  } +  /* return current page */ -static inline term* get_current_term(){ -  gint page = gtk_notebook_get_current_page(GTK_NOTEBOOK(svte.notebook)); +static inline term* get_current_term(window *w){ +  gint page = gtk_notebook_get_current_page(GTK_NOTEBOOK(w->notebook));    struct term *t; -  t = get_nth_term(page); +  t = get_nth_term(w, page);    return t;  } @@ -119,46 +119,50 @@ static void launch_url(char *url) {  /* key event handler */ -gboolean event_key(GtkWidget *widget, GdkEventKey *event) { +gboolean event_key(GtkWidget *widget, GdkEventKey *event, window *w) {    guint(g) = event->keyval;    if ((event->state & (GDK_CONTROL_MASK|GDK_SHIFT_MASK)) ==        (GDK_CONTROL_MASK|GDK_SHIFT_MASK)) { +    if (g == GDK_N) { +      new_window(); +      return TRUE; +    }      if (g == GDK_T) { -      tab_new(); +      tab_new(w);        return TRUE;      }      if (g == GDK_H) { -      tab_togglebar(); +      tab_togglebar(w);        return TRUE;      }      if (g == GDK_W) { -      tab_close(); +      tab_close(NULL, w);        return TRUE;      }      if (g == GDK_V) { -      vte_terminal_paste_clipboard(VTE_TERMINAL(get_current_term()->vte)); +      vte_terminal_paste_clipboard(VTE_TERMINAL(get_current_term(w)->vte));        return TRUE;      }      if (g == GDK_C) { -      vte_terminal_copy_clipboard(VTE_TERMINAL(get_current_term()->vte)); +      vte_terminal_copy_clipboard(VTE_TERMINAL(get_current_term(w)->vte));        return TRUE;      }    }    if ((event->state & (GDK_MOD1_MASK) ) == (GDK_MOD1_MASK)) {      if (g == GDK_Left) { -      tab_switch(FALSE); +      tab_switch(FALSE, w);        return TRUE;      }      if (g == GDK_Right) { -      tab_switch(TRUE); +      tab_switch(TRUE, w);        return TRUE;      }      if (g == GDK_F11) {        if(config->fullscreen) { -        gtk_window_unfullscreen(GTK_WINDOW(svte.win)); +        gtk_window_unfullscreen(GTK_WINDOW(widget));          config->fullscreen = FALSE;        } else { -        gtk_window_fullscreen(GTK_WINDOW(svte.win)); +        gtk_window_fullscreen(GTK_WINDOW(widget));          config->fullscreen = TRUE;        }        return TRUE; @@ -187,34 +191,47 @@ gboolean event_button(GtkWidget *widget, GdkEventButton *button_event) {    return FALSE;  } +/* function that closes the current window */ +static void window_close(struct window *w) { + +  gtk_widget_destroy(w->notebook); +  gtk_widget_destroy(w->win); +  g_free(w); + +  GList *list = gtk_window_list_toplevels(); +  if(g_list_length(list) < 1) { +    quit(); +  } +} +  /* function closes the current tab */ -static void tab_close() { -  gint page = gtk_notebook_get_current_page(GTK_NOTEBOOK(svte.notebook)); -  struct term *t; -  t = get_nth_term(page); -  gtk_notebook_remove_page(GTK_NOTEBOOK(svte.notebook), page); +static void tab_close(VteTerminal *term, struct window *w) { + +  gint page = gtk_notebook_get_current_page(GTK_NOTEBOOK(w->notebook)); +  struct term *t = get_nth_term(w, page); +  gtk_notebook_remove_page(GTK_NOTEBOOK(w->notebook), page);    g_free(t); -  if (gtk_notebook_get_n_pages(GTK_NOTEBOOK(svte.notebook)) == 1) { -    gtk_notebook_set_show_tabs(GTK_NOTEBOOK(svte.notebook), FALSE); +  if (gtk_notebook_get_n_pages(GTK_NOTEBOOK(w->notebook)) == 1) { +    gtk_notebook_set_show_tabs(GTK_NOTEBOOK(w->notebook), FALSE);      gtk_widget_grab_focus( -        gtk_notebook_get_nth_page(GTK_NOTEBOOK(svte.notebook), -          gtk_notebook_get_current_page(GTK_NOTEBOOK(svte.notebook)))); +        gtk_notebook_get_nth_page(GTK_NOTEBOOK(w->notebook), +          gtk_notebook_get_current_page(GTK_NOTEBOOK(w->notebook))));    } -  if (gtk_notebook_get_n_pages(GTK_NOTEBOOK(svte.notebook)) == 0) { -    quit(); +  if (gtk_notebook_get_n_pages(GTK_NOTEBOOK(w->notebook)) == 0) { +    window_close(w);    }  }  /* toggle the visibility of the notebook tab */ -static void tab_togglebar() { +static void tab_togglebar(struct window *w) { -  if(gtk_notebook_get_show_tabs(GTK_NOTEBOOK(svte.notebook))) { -    gtk_notebook_set_show_tabs(GTK_NOTEBOOK(svte.notebook), FALSE); +  if(gtk_notebook_get_show_tabs(GTK_NOTEBOOK(w->notebook))) { +    gtk_notebook_set_show_tabs(GTK_NOTEBOOK(w->notebook), FALSE);    }    else { -    if (gtk_notebook_get_n_pages(GTK_NOTEBOOK(svte.notebook)) != 1)  { -      gtk_notebook_set_show_tabs(GTK_NOTEBOOK(svte.notebook), TRUE);  +    if (gtk_notebook_get_n_pages(GTK_NOTEBOOK(w->notebook)) != 1)  { +      gtk_notebook_set_show_tabs(GTK_NOTEBOOK(w->notebook), TRUE);       }    }  } @@ -247,22 +264,22 @@ static char* tab_get_cwd(struct term* t)  }  /* callback for when tabs switch */ -static void tab_switch(gboolean b) { -  gint(current) = gtk_notebook_get_current_page(GTK_NOTEBOOK(svte.notebook)); +static void tab_switch(gboolean b, struct window *w) { +  gint(current) = gtk_notebook_get_current_page(GTK_NOTEBOOK(w->notebook));    if(b) { -    if (current == gtk_notebook_get_n_pages(GTK_NOTEBOOK(svte.notebook)) -1 ) { +    if (current == gtk_notebook_get_n_pages(GTK_NOTEBOOK(w->notebook)) -1 ) {        current = 0;      } else {        current = current + 1;      }    } else {      if (current == 0) { -      current = gtk_notebook_get_n_pages(GTK_NOTEBOOK(svte.notebook)) - 1; +      current = gtk_notebook_get_n_pages(GTK_NOTEBOOK(w->notebook)) - 1;      } else {        current = current -1;      }    } -  gtk_notebook_set_current_page(GTK_NOTEBOOK(svte.notebook), current); +  gtk_notebook_set_current_page(GTK_NOTEBOOK(w->notebook), current);  }  /* setup the whacky geometry hints for gtk */ @@ -285,7 +302,7 @@ static void tab_geometry_hints(term *t) {    hints.height_inc = char_height;    gtk_window_set_geometry_hints( -      GTK_WINDOW(svte.win), +      GTK_WINDOW(t->w->win),        GTK_WIDGET(t->vte),        &hints,        GDK_HINT_RESIZE_INC | GDK_HINT_MIN_SIZE | GDK_HINT_BASE_SIZE); @@ -297,7 +314,7 @@ static void tab_title(GtkWidget *widget, term *t) {        GTK_LABEL(t->label),        vte_terminal_get_window_title(VTE_TERMINAL(t->vte))); -  if(t  == get_current_term()) {   +  if(t  == get_current_term(t->w)) {        set_window_title(t);    }  }  @@ -310,19 +327,19 @@ static void set_window_title(term *t){      title = "svte";    } -  gtk_window_set_title(GTK_WINDOW(svte.win), title); +  gtk_window_set_title(GTK_WINDOW(t->w->win), title);  }  /* focus the tab */  static void tab_focus(GtkNotebook *notebook, GtkNotebookPage *page, -    guint page_num, gpointer user_data) { +    guint page_num, struct window *w) {    struct term *t; -  t = get_nth_term(page_num); +  t = get_nth_term(w, page_num);    set_window_title(t);  }  /* create a new tab */ -static void tab_new() { +static void tab_new(struct window *w) {    term *t;    int tmp; @@ -336,30 +353,31 @@ static void tab_new() {    t = g_new0(term, 1);    t->label = gtk_label_new(""); +  t->w = w;    t->vte = vte_terminal_new(); -  int index = gtk_notebook_append_page(GTK_NOTEBOOK(svte.notebook), t->vte, +  int index = gtk_notebook_append_page(GTK_NOTEBOOK(w->notebook), t->vte,        t->label); -  gtk_notebook_set_tab_reorderable(GTK_NOTEBOOK(svte.notebook), t->vte, TRUE); +  gtk_notebook_set_tab_reorderable(GTK_NOTEBOOK(w->notebook), t->vte, TRUE);    if (index == 0) { -    gtk_notebook_set_show_tabs(GTK_NOTEBOOK(svte.notebook), FALSE); +    gtk_notebook_set_show_tabs(GTK_NOTEBOOK(w->notebook), FALSE);      vte_terminal_fork_command_full(VTE_TERMINAL(t->vte),           VTE_PTY_DEFAULT, NULL,           args, NULL, G_SPAWN_SEARCH_PATH, NULL, NULL, t->pid, NULL);      tab_geometry_hints(t);    } else { -    struct term *previous = get_nth_term(gtk_notebook_get_current_page(GTK_NOTEBOOK(svte.notebook))); +    struct term *previous = get_nth_term(w, gtk_notebook_get_current_page(GTK_NOTEBOOK(w->notebook)));      vte_terminal_fork_command_full(VTE_TERMINAL(t->vte),           VTE_PTY_DEFAULT, tab_get_cwd(previous),           args, NULL, G_SPAWN_SEARCH_PATH, NULL, NULL, t->pid, NULL); -    gtk_notebook_set_show_tabs(GTK_NOTEBOOK(svte.notebook), TRUE); +    gtk_notebook_set_show_tabs(GTK_NOTEBOOK(w->notebook), TRUE);    }    g_object_set_qdata_full(G_OBJECT(gtk_notebook_get_nth_page( -          (GtkNotebook*)svte.notebook, index)), term_data_id, t, NULL); +          (GtkNotebook*)w->notebook, index)), term_data_id, t, NULL); -  g_signal_connect(G_OBJECT(t->vte), "child-exited", G_CALLBACK(tab_close), NULL); +  g_signal_connect(G_OBJECT(t->vte), "child-exited", G_CALLBACK(tab_close), w);    g_signal_connect(G_OBJECT(t->vte), "window-title-changed", G_CALLBACK(tab_title), t);    g_signal_connect(G_OBJECT(t->vte), "button-press-event", G_CALLBACK(event_button), NULL); @@ -391,39 +409,41 @@ static void tab_new() {    vte_terminal_match_set_cursor_type(VTE_TERMINAL(t->vte), tmp,        GDK_HAND2); -  gtk_widget_show_all(svte.notebook); -  gtk_notebook_set_current_page(GTK_NOTEBOOK(svte.notebook), index); +  gtk_widget_show_all(w->notebook); +  gtk_notebook_set_current_page(GTK_NOTEBOOK(w->notebook), index);    gtk_widget_grab_focus(t->vte);  }  /* setup the main window */ -static void configure_window() { +static void new_window() { + + +  window *w = g_new0(window, 1); +    term_data_id = g_quark_from_static_string("svte"); -  svte.notebook = gtk_notebook_new(); -  gtk_notebook_set_show_border(GTK_NOTEBOOK(svte.notebook), FALSE); -  gtk_notebook_set_scrollable(GTK_NOTEBOOK(svte.notebook), TRUE); -  svte.win = gtk_window_new(GTK_WINDOW_TOPLEVEL); +  w->notebook = gtk_notebook_new(); +  gtk_notebook_set_show_border(GTK_NOTEBOOK(w->notebook), FALSE); +  gtk_notebook_set_scrollable(GTK_NOTEBOOK(w->notebook), TRUE); +  w->win = gtk_window_new(GTK_WINDOW_TOPLEVEL);    if (config->fullscreen) { -    gtk_window_fullscreen(GTK_WINDOW(svte.win)); +    gtk_window_fullscreen(GTK_WINDOW(w->win));    } -  gtk_window_set_default_size(GTK_WINDOW(svte.win), +  gtk_window_set_default_size(GTK_WINDOW(w->win),        config->window_width,        config->window_height); -  gtk_container_add(GTK_CONTAINER(svte.win), svte.notebook); +  gtk_container_add(GTK_CONTAINER(w->win), w->notebook); -  tab_new(); +  tab_new(w); -  gtk_widget_show_all(svte.win); +  gtk_widget_show_all(w->win);    /* add the callback signals */ -  g_signal_connect(G_OBJECT(svte.win), "destroy", G_CALLBACK(quit), NULL); -  g_signal_connect(svte.win, "key-press-event", G_CALLBACK(event_key), NULL); -  g_signal_connect(G_OBJECT(svte.notebook), "switch-page", G_CALLBACK(tab_focus), -      NULL); +  g_signal_connect(G_OBJECT(w->win), "key-press-event", G_CALLBACK(event_key), w); +  g_signal_connect(G_OBJECT(w->notebook), "switch-page", G_CALLBACK(tab_focus), w); -  set_window_title(get_current_term()); +  set_window_title(get_current_term(w));  }  @@ -555,7 +575,8 @@ int main(int argc, char* argv[]) {    }    parse_config_file(config_file); -  configure_window(); +  new_window(); +    gtk_main();    return 0;  } | 
