Blame src/interface.cpp

Packit 76ec6a
/* -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
Packit 76ec6a
/* Procman - main window
Packit 76ec6a
 * Copyright (C) 2001 Kevin Vandersloot
Packit 76ec6a
 *
Packit 76ec6a
 * This program is free software; you can redistribute it and/or
Packit 76ec6a
 * modify it under the terms of the GNU General Public License
Packit 76ec6a
 * as published by the Free Software Foundation; either version 2
Packit 76ec6a
 * of the License, or (at your option) any later version.
Packit 76ec6a
 *
Packit 76ec6a
 * This program is distributed in the hope that it will be useful,
Packit 76ec6a
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 76ec6a
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit 76ec6a
 * GNU General Public License for more details.
Packit 76ec6a
 *
Packit 76ec6a
 * You should have received a copy of the GNU Library General Public
Packit 76ec6a
 * License along with this program; if not, see <http://www.gnu.org/licenses/>.
Packit 76ec6a
 *
Packit 76ec6a
 */
Packit 76ec6a
Packit 76ec6a
Packit 76ec6a
#include <config.h>
Packit 76ec6a
Packit 76ec6a
#include <glib/gi18n.h>
Packit 76ec6a
#include <gtk/gtk.h>
Packit 76ec6a
#include <sys/types.h>
Packit 76ec6a
#include <sys/stat.h>
Packit 76ec6a
#include <unistd.h>
Packit 76ec6a
#include <string.h>
Packit 76ec6a
#include <signal.h>
Packit 76ec6a
#include <gdk/gdkkeysyms.h>
Packit 76ec6a
#include <math.h>
Packit 76ec6a
Packit 76ec6a
#include "interface.h"
Packit 76ec6a
#include "proctable.h"
Packit 76ec6a
#include "procactions.h"
Packit 76ec6a
#include "procdialogs.h"
Packit 76ec6a
#include "memmaps.h"
Packit 76ec6a
#include "openfiles.h"
Packit 76ec6a
#include "procproperties.h"
Packit 76ec6a
#include "load-graph.h"
Packit 76ec6a
#include "util.h"
Packit 76ec6a
#include "disks.h"
Packit 76ec6a
#include "settings-keys.h"
Packit 76ec6a
#include "legacy/gsm_color_button.h"
Packit 76ec6a
Packit 76ec6a
static const char* LOAD_GRAPH_CSS = "\
Packit 76ec6a
.loadgraph {\
Packit 76ec6a
    background: linear-gradient(to bottom,\
Packit 76ec6a
                      @theme_bg_color,\
Packit 76ec6a
                      @theme_base_color\
Packit 76ec6a
                      );\
Packit 76ec6a
    color: mix (@theme_fg_color, @theme_bg_color, 0.5);\
Packit 76ec6a
}\
Packit 76ec6a
";
Packit 76ec6a
Packit 76ec6a
static gboolean
Packit 76ec6a
cb_window_key_press_event (GtkWidget *widget, GdkEvent *event, gpointer user_data)
Packit 76ec6a
{
Packit 76ec6a
    const char *current_page = gtk_stack_get_visible_child_name (GTK_STACK (GsmApplication::get()->stack));
Packit 76ec6a
Packit 76ec6a
    if (strcmp (current_page, "processes") == 0)
Packit 76ec6a
        return gtk_search_bar_handle_event (GTK_SEARCH_BAR (user_data), event);
Packit 76ec6a
    
Packit 76ec6a
    return FALSE;
Packit 76ec6a
}
Packit 76ec6a
Packit 76ec6a
static void
Packit 76ec6a
search_text_changed (GtkEditable *entry, gpointer data)
Packit 76ec6a
{
Packit 76ec6a
    GsmApplication * const app = static_cast<GsmApplication *>(data);
Packit 76ec6a
    gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (gtk_tree_model_sort_get_model (
Packit 76ec6a
                                    GTK_TREE_MODEL_SORT (gtk_tree_view_get_model(
Packit 76ec6a
                                    GTK_TREE_VIEW (app->tree))))));
Packit 76ec6a
}
Packit 76ec6a
Packit 76ec6a
static void 
Packit 76ec6a
create_proc_view(GsmApplication *app, GtkBuilder * builder)
Packit 76ec6a
{
Packit 76ec6a
    GsmTreeView *proctree;
Packit 76ec6a
    GtkScrolledWindow *scrolled;
Packit 76ec6a
Packit 76ec6a
    proctree = proctable_new (app);
Packit 76ec6a
    scrolled = GTK_SCROLLED_WINDOW (gtk_builder_get_object (builder, "processes_scrolled"));
Packit 76ec6a
Packit 76ec6a
    gtk_container_add (GTK_CONTAINER (scrolled), GTK_WIDGET (proctree));
Packit 76ec6a
Packit 76ec6a
    app->proc_actionbar_revealer = GTK_REVEALER (gtk_builder_get_object (builder, "proc_actionbar_revealer"));
Packit 76ec6a
Packit 76ec6a
    /* create popup_menu for the processes tab */
Packit 76ec6a
    GMenuModel *menu_model = G_MENU_MODEL (gtk_builder_get_object (builder, "process-popup-menu"));
Packit 76ec6a
    app->popup_menu = GTK_MENU (gtk_menu_new_from_model (menu_model));
Packit 76ec6a
    gtk_menu_attach_to_widget (app->popup_menu, GTK_WIDGET (app->main_window), NULL);
Packit 76ec6a
    
Packit 76ec6a
    app->search_bar = GTK_SEARCH_BAR (gtk_builder_get_object (builder, "proc_searchbar"));
Packit 76ec6a
    app->search_entry = GTK_SEARCH_ENTRY (gtk_builder_get_object (builder, "proc_searchentry"));
Packit 76ec6a
    
Packit 76ec6a
    gtk_search_bar_connect_entry (app->search_bar, GTK_ENTRY (app->search_entry));
Packit 76ec6a
    g_signal_connect (app->main_window, "key-press-event",
Packit 76ec6a
                      G_CALLBACK (cb_window_key_press_event), app->search_bar);
Packit 76ec6a
                  
Packit 76ec6a
    g_signal_connect (app->search_entry, "changed", G_CALLBACK (search_text_changed), app);
Packit 76ec6a
Packit 76ec6a
    g_object_bind_property (app->search_bar, "search-mode-enabled", app->search_button, "active", (GBindingFlags)(G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE));
Packit 76ec6a
}
Packit 76ec6a
Packit 76ec6a
void
Packit 76ec6a
cb_cpu_color_changed (GsmColorButton *cp, gpointer data)
Packit 76ec6a
{
Packit 76ec6a
    guint cpu_i = GPOINTER_TO_UINT (data);
Packit 76ec6a
    auto settings = Gio::Settings::create (GSM_GSETTINGS_SCHEMA);
Packit 76ec6a
Packit 76ec6a
    /* Get current values */
Packit 76ec6a
    GVariant *cpu_colors_var = g_settings_get_value (settings->gobj(), GSM_SETTING_CPU_COLORS);
Packit 76ec6a
    gsize children_n = g_variant_n_children(cpu_colors_var);
Packit 76ec6a
Packit 76ec6a
    /* Create builder to contruct new setting with updated value for cpu i */
Packit 76ec6a
    GVariantBuilder builder;
Packit 76ec6a
    g_variant_builder_init(&builder, G_VARIANT_TYPE_ARRAY);
Packit 76ec6a
Packit 76ec6a
    for (guint i = 0; i < children_n; i++) {
Packit 76ec6a
        if(cpu_i == i) {
Packit 76ec6a
            gchar *color;
Packit 76ec6a
            GdkRGBA button_color;
Packit 76ec6a
            gsm_color_button_get_color(cp, &button_color);
Packit 76ec6a
            color = gdk_rgba_to_string (&button_color);
Packit 76ec6a
            g_variant_builder_add(&builder, "(us)", i, color);
Packit 76ec6a
            g_free (color);
Packit 76ec6a
        } else {
Packit 76ec6a
            g_variant_builder_add_value(&builder,
Packit 76ec6a
                                        g_variant_get_child_value(cpu_colors_var, i));
Packit 76ec6a
        }
Packit 76ec6a
    }
Packit 76ec6a
Packit 76ec6a
    /* Just set the value and let the changed::cpu-colors signal callback do the rest. */
Packit 76ec6a
    settings->set_value (GSM_SETTING_CPU_COLORS, Glib::wrap (g_variant_builder_end(&builder)));
Packit 76ec6a
}
Packit 76ec6a
Packit 76ec6a
static void change_settings_color(Gio::Settings& settings, const char *key,
Packit 76ec6a
                                  GsmColorButton *cp)
Packit 76ec6a
{
Packit 76ec6a
    GdkRGBA c;
Packit 76ec6a
    char *color;
Packit 76ec6a
Packit 76ec6a
    gsm_color_button_get_color(cp, &c);
Packit 76ec6a
    color = gdk_rgba_to_string (&c);
Packit 76ec6a
    settings.set_string (key, color);
Packit 76ec6a
    g_free (color);
Packit 76ec6a
}
Packit 76ec6a
Packit 76ec6a
static void
Packit 76ec6a
cb_mem_color_changed (GsmColorButton *cp, gpointer data)
Packit 76ec6a
{
Packit 76ec6a
    GsmApplication *app = (GsmApplication *) data;
Packit 76ec6a
    change_settings_color (*app->settings.operator->(), GSM_SETTING_MEM_COLOR, cp);
Packit 76ec6a
}
Packit 76ec6a
Packit 76ec6a
Packit 76ec6a
static void
Packit 76ec6a
cb_swap_color_changed (GsmColorButton *cp, gpointer data)
Packit 76ec6a
{
Packit 76ec6a
    GsmApplication *app = (GsmApplication *) data;
Packit 76ec6a
    change_settings_color (*app->settings.operator->(), GSM_SETTING_SWAP_COLOR, cp);
Packit 76ec6a
}
Packit 76ec6a
Packit 76ec6a
static void
Packit 76ec6a
cb_net_in_color_changed (GsmColorButton *cp, gpointer data)
Packit 76ec6a
{
Packit 76ec6a
    GsmApplication *app = (GsmApplication *) data;
Packit 76ec6a
    change_settings_color (*app->settings.operator->(), GSM_SETTING_NET_IN_COLOR, cp);
Packit 76ec6a
}
Packit 76ec6a
Packit 76ec6a
static void
Packit 76ec6a
cb_net_out_color_changed (GsmColorButton *cp, gpointer data)
Packit 76ec6a
{
Packit 76ec6a
    GsmApplication *app = (GsmApplication *) data;
Packit 76ec6a
    change_settings_color(*app->settings.operator->(), GSM_SETTING_NET_OUT_COLOR, cp);
Packit 76ec6a
}
Packit 76ec6a
Packit 76ec6a
static void
Packit 76ec6a
create_sys_view (GsmApplication *app, GtkBuilder * builder)
Packit 76ec6a
{
Packit 76ec6a
    GtkBox *cpu_graph_box, *mem_graph_box, *net_graph_box;
Packit 76ec6a
    GtkLabel *label,*cpu_label;
Packit 76ec6a
    GtkGrid *table;
Packit 76ec6a
    GsmColorButton *color_picker;
Packit 76ec6a
    GtkCssProvider *provider;
Packit 76ec6a
Packit 76ec6a
    LoadGraph *cpu_graph, *mem_graph, *net_graph;
Packit 76ec6a
Packit 76ec6a
    gint i;
Packit 76ec6a
    gchar *title_text;
Packit 76ec6a
    gchar *label_text;
Packit 76ec6a
    gchar *title_template;
Packit 76ec6a
Packit 76ec6a
    provider = gtk_css_provider_new ();
Packit 76ec6a
    gtk_css_provider_load_from_data (provider, LOAD_GRAPH_CSS, -1, NULL);
Packit 76ec6a
    gtk_style_context_add_provider_for_screen (gdk_screen_get_default (), GTK_STYLE_PROVIDER (provider), GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
Packit 76ec6a
    // Translators: color picker title, %s is CPU, Memory, Swap, Receiving, Sending
Packit 76ec6a
    title_template = g_strdup(_("Pick a Color for “%s”"));
Packit 76ec6a
Packit 76ec6a
    /* The CPU BOX */
Packit 76ec6a
    
Packit 76ec6a
    cpu_graph_box = GTK_BOX (gtk_builder_get_object (builder, "cpu_graph_box"));
Packit 76ec6a
Packit 76ec6a
    cpu_graph = new LoadGraph(LOAD_GRAPH_CPU);
Packit 76ec6a
    gtk_widget_set_size_request (GTK_WIDGET(load_graph_get_widget(cpu_graph)), -1, 70);
Packit 76ec6a
    gtk_box_pack_start (cpu_graph_box,
Packit 76ec6a
                        GTK_WIDGET (load_graph_get_widget(cpu_graph)),
Packit 76ec6a
                        TRUE,
Packit 76ec6a
                        TRUE,
Packit 76ec6a
                        0);
Packit 76ec6a
Packit 76ec6a
    GtkGrid* cpu_table = GTK_GRID (gtk_builder_get_object (builder, "cpu_table"));
Packit 76ec6a
    gint cols = 4;
Packit 76ec6a
    for (i=0;i<app->config.num_cpus; i++) {
Packit 76ec6a
        GtkBox *temp_hbox;
Packit 76ec6a
Packit 76ec6a
        temp_hbox = GTK_BOX (gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0));
Packit 76ec6a
        gtk_widget_show (GTK_WIDGET (temp_hbox));
Packit 76ec6a
        if (i < cols) {
Packit 76ec6a
            gtk_grid_insert_column(cpu_table, i%cols);
Packit 76ec6a
        }
Packit 76ec6a
        if ((i+1)%cols ==cols) {
Packit 76ec6a
            gtk_grid_insert_row(cpu_table, (i+1)/cols);
Packit 76ec6a
        }
Packit 76ec6a
        gtk_grid_attach(cpu_table, GTK_WIDGET (temp_hbox), i%cols, i/cols, 1, 1);
Packit 76ec6a
        color_picker = gsm_color_button_new (&cpu_graph->colors.at(i), GSMCP_TYPE_CPU);
Packit 76ec6a
        g_signal_connect (G_OBJECT (color_picker), "color-set",
Packit 76ec6a
                          G_CALLBACK (cb_cpu_color_changed), GINT_TO_POINTER (i));
Packit 76ec6a
        gtk_box_pack_start (temp_hbox, GTK_WIDGET (color_picker), FALSE, TRUE, 0);
Packit 76ec6a
        gtk_widget_set_size_request(GTK_WIDGET(color_picker), 32, -1);
Packit 76ec6a
        if(app->config.num_cpus == 1) {
Packit 76ec6a
            label_text = g_strdup (_("CPU"));
Packit 76ec6a
        } else {
Packit 76ec6a
            label_text = g_strdup_printf (_("CPU%d"), i+1);
Packit 76ec6a
        }
Packit 76ec6a
        title_text = g_strdup_printf(title_template, label_text);
Packit 76ec6a
        label = GTK_LABEL (gtk_label_new (label_text));
Packit 76ec6a
        gsm_color_button_set_title(color_picker, title_text);
Packit 76ec6a
        g_free(title_text);
Packit 76ec6a
        gtk_box_pack_start (temp_hbox, GTK_WIDGET (label), FALSE, FALSE, 6);
Packit 76ec6a
        gtk_widget_show (GTK_WIDGET (label));
Packit 76ec6a
        g_free (label_text);
Packit 76ec6a
Packit 76ec6a
        cpu_label = GTK_LABEL (gtk_label_new (NULL));
Packit 76ec6a
Packit 76ec6a
        gtk_widget_set_valign (GTK_WIDGET (cpu_label), GTK_ALIGN_CENTER);
Packit 76ec6a
        gtk_widget_set_halign (GTK_WIDGET (cpu_label), GTK_ALIGN_START);
Packit 76ec6a
        gtk_box_pack_start (temp_hbox, GTK_WIDGET (cpu_label), FALSE, FALSE, 0);
Packit 76ec6a
        gtk_widget_show (GTK_WIDGET (cpu_label));
Packit 76ec6a
        load_graph_get_labels(cpu_graph)->cpu[i] = cpu_label;
Packit 76ec6a
Packit 76ec6a
    }
Packit 76ec6a
Packit 76ec6a
    app->cpu_graph = cpu_graph;
Packit 76ec6a
Packit 76ec6a
    /** The memory box */
Packit 76ec6a
    
Packit 76ec6a
    mem_graph_box = GTK_BOX (gtk_builder_get_object (builder, "mem_graph_box"));
Packit 76ec6a
Packit 76ec6a
    mem_graph = new LoadGraph(LOAD_GRAPH_MEM);
Packit 76ec6a
    gtk_widget_set_size_request (GTK_WIDGET(load_graph_get_widget(mem_graph)), -1, 70);
Packit 76ec6a
    gtk_box_pack_start (mem_graph_box,
Packit 76ec6a
                        GTK_WIDGET (load_graph_get_widget(mem_graph)),
Packit 76ec6a
                        TRUE,
Packit 76ec6a
                        TRUE,
Packit 76ec6a
                        0);
Packit 76ec6a
Packit 76ec6a
    table = GTK_GRID (gtk_builder_get_object (builder, "mem_table"));
Packit 76ec6a
Packit 76ec6a
    color_picker = load_graph_get_mem_color_picker(mem_graph);
Packit 76ec6a
    g_signal_connect (G_OBJECT (color_picker), "color-set",
Packit 76ec6a
                      G_CALLBACK (cb_mem_color_changed), app);
Packit 76ec6a
    title_text = g_strdup_printf(title_template, _("Memory"));
Packit 76ec6a
    gsm_color_button_set_title(color_picker, title_text);
Packit 76ec6a
    g_free(title_text);
Packit 76ec6a
Packit 76ec6a
    label = GTK_LABEL (gtk_builder_get_object(builder, "memory_label"));
Packit 76ec6a
Packit 76ec6a
    gtk_grid_attach_next_to (table, GTK_WIDGET (color_picker), GTK_WIDGET (label), GTK_POS_LEFT, 1, 2);
Packit 76ec6a
    gtk_grid_attach_next_to (table, GTK_WIDGET (load_graph_get_labels(mem_graph)->memory), GTK_WIDGET (label), GTK_POS_BOTTOM, 1, 1);
Packit 76ec6a
Packit 76ec6a
    color_picker = load_graph_get_swap_color_picker(mem_graph);
Packit 76ec6a
    g_signal_connect (G_OBJECT (color_picker), "color-set",
Packit 76ec6a
                      G_CALLBACK (cb_swap_color_changed), app);
Packit 76ec6a
    title_text = g_strdup_printf(title_template, _("Swap"));
Packit 76ec6a
    gsm_color_button_set_title(GSM_COLOR_BUTTON(color_picker), title_text);
Packit 76ec6a
    g_free(title_text);
Packit 76ec6a
Packit 76ec6a
    label = GTK_LABEL (gtk_builder_get_object(builder, "swap_label"));
Packit 76ec6a
Packit 76ec6a
    gtk_grid_attach_next_to (table, GTK_WIDGET (color_picker), GTK_WIDGET (label), GTK_POS_LEFT, 1, 2);
Packit 76ec6a
    gtk_grid_attach_next_to (table, GTK_WIDGET (load_graph_get_labels(mem_graph)->swap), GTK_WIDGET (label), GTK_POS_BOTTOM, 1, 1);
Packit 76ec6a
Packit 76ec6a
    app->mem_graph = mem_graph;
Packit 76ec6a
Packit 76ec6a
    /* The net box */
Packit 76ec6a
    
Packit 76ec6a
    net_graph_box = GTK_BOX (gtk_builder_get_object (builder, "net_graph_box"));
Packit 76ec6a
Packit 76ec6a
    net_graph = new LoadGraph(LOAD_GRAPH_NET);
Packit 76ec6a
    gtk_widget_set_size_request (GTK_WIDGET(load_graph_get_widget(net_graph)), -1, 70);
Packit 76ec6a
    gtk_box_pack_start (net_graph_box,
Packit 76ec6a
                        GTK_WIDGET (load_graph_get_widget(net_graph)),
Packit 76ec6a
                        TRUE,
Packit 76ec6a
                        TRUE,
Packit 76ec6a
                        0);
Packit 76ec6a
Packit 76ec6a
    table = GTK_GRID (gtk_builder_get_object (builder, "net_table"));
Packit 76ec6a
Packit 76ec6a
    color_picker = gsm_color_button_new (
Packit 76ec6a
        &net_graph->colors.at(0), GSMCP_TYPE_NETWORK_IN);
Packit 76ec6a
    gtk_widget_set_valign (GTK_WIDGET(color_picker), GTK_ALIGN_CENTER);
Packit 76ec6a
    g_signal_connect (G_OBJECT (color_picker), "color-set",
Packit 76ec6a
                      G_CALLBACK (cb_net_in_color_changed), app);
Packit 76ec6a
    title_text = g_strdup_printf(title_template, _("Receiving"));
Packit 76ec6a
    gsm_color_button_set_title(color_picker, title_text);
Packit 76ec6a
    g_free(title_text);
Packit 76ec6a
Packit 76ec6a
    label = GTK_LABEL (gtk_builder_get_object(builder, "receiving_label"));
Packit 76ec6a
    gtk_grid_attach_next_to (table, GTK_WIDGET (color_picker), GTK_WIDGET (label), GTK_POS_LEFT, 1, 2);
Packit 76ec6a
    gtk_grid_attach_next_to (table, GTK_WIDGET (load_graph_get_labels(net_graph)->net_in), GTK_WIDGET (label), GTK_POS_RIGHT, 1, 1);
Packit 76ec6a
    label = GTK_LABEL (gtk_builder_get_object(builder, "total_received_label"));
Packit 76ec6a
    gtk_grid_attach_next_to (table, GTK_WIDGET (load_graph_get_labels(net_graph)->net_in_total), GTK_WIDGET (label), GTK_POS_RIGHT, 1, 1);
Packit 76ec6a
Packit 76ec6a
    color_picker = gsm_color_button_new (
Packit 76ec6a
        &net_graph->colors.at(1), GSMCP_TYPE_NETWORK_OUT);
Packit 76ec6a
    gtk_widget_set_valign (GTK_WIDGET(color_picker), GTK_ALIGN_CENTER);
Packit 76ec6a
    gtk_widget_set_hexpand (GTK_WIDGET(color_picker), true);
Packit 76ec6a
    gtk_widget_set_halign (GTK_WIDGET(color_picker), GTK_ALIGN_END);
Packit 76ec6a
Packit 76ec6a
    g_signal_connect (G_OBJECT (color_picker), "color-set",
Packit 76ec6a
                      G_CALLBACK (cb_net_out_color_changed), app);
Packit 76ec6a
    title_text = g_strdup_printf(title_template, _("Sending"));
Packit 76ec6a
    gsm_color_button_set_title(color_picker, title_text);
Packit 76ec6a
    g_free(title_text);
Packit 76ec6a
Packit 76ec6a
    label = GTK_LABEL (gtk_builder_get_object(builder, "sending_label"));
Packit 76ec6a
    gtk_grid_attach_next_to (table, GTK_WIDGET (color_picker), GTK_WIDGET (label), GTK_POS_LEFT, 1, 2);
Packit 76ec6a
    gtk_grid_attach_next_to (table, GTK_WIDGET (load_graph_get_labels(net_graph)->net_out), GTK_WIDGET (label), GTK_POS_RIGHT, 1, 1);
Packit 76ec6a
    label = GTK_LABEL (gtk_builder_get_object(builder, "total_sent_label"));
Packit 76ec6a
    gtk_grid_attach_next_to (table, GTK_WIDGET (load_graph_get_labels(net_graph)->net_out_total), GTK_WIDGET (label), GTK_POS_RIGHT, 1, 1);
Packit 76ec6a
    gtk_widget_set_hexpand (GTK_WIDGET(load_graph_get_labels(net_graph)->net_out_total), true);
Packit 76ec6a
    gtk_widget_set_halign (GTK_WIDGET(load_graph_get_labels(net_graph)->net_out_total), GTK_ALIGN_START);
Packit 76ec6a
Packit 76ec6a
    gtk_widget_set_hexpand (GTK_WIDGET(load_graph_get_labels(net_graph)->net_out), true);
Packit 76ec6a
    gtk_widget_set_halign (GTK_WIDGET(load_graph_get_labels(net_graph)->net_out), GTK_ALIGN_START);
Packit 76ec6a
Packit 76ec6a
Packit 76ec6a
    app->net_graph = net_graph;
Packit 76ec6a
    g_free (title_template);
Packit 76ec6a
Packit 76ec6a
}
Packit 76ec6a
Packit 76ec6a
static void
Packit 76ec6a
on_activate_about (GSimpleAction *, GVariant *, gpointer data)
Packit 76ec6a
{
Packit 76ec6a
    GsmApplication *app = (GsmApplication *) data;
Packit 76ec6a
Packit 76ec6a
    const gchar * const authors[] = {
Packit 76ec6a
        "Kevin Vandersloot",
Packit 76ec6a
        "Erik Johnsson",
Packit 76ec6a
        "Jorgen Scheibengruber",
Packit 76ec6a
        "Benoît Dejean",
Packit 76ec6a
        "Paolo Borelli",
Packit 76ec6a
        "Karl Lattimer",
Packit 76ec6a
        "Chris Kühl",
Packit 76ec6a
        "Robert Roth",
Packit 76ec6a
        "Stefano Facchini",
Packit 76ec6a
        NULL
Packit 76ec6a
    };
Packit 76ec6a
Packit 76ec6a
    const gchar * const documenters[] = {
Packit 76ec6a
        "Bill Day",
Packit 76ec6a
        "Sun Microsystems",
Packit 76ec6a
        NULL
Packit 76ec6a
    };
Packit 76ec6a
Packit 76ec6a
    const gchar * const artists[] = {
Packit 76ec6a
        "Baptiste Mille-Mathias",
Packit 76ec6a
        NULL
Packit 76ec6a
    };
Packit 76ec6a
Packit 76ec6a
    gtk_show_about_dialog (
Packit 76ec6a
        GTK_WINDOW (app->main_window),
Packit 76ec6a
        "name",                 _("System Monitor"),
Packit 76ec6a
        "comments",             _("View current processes and monitor "
Packit 76ec6a
                                  "system state"),
Packit 76ec6a
        "version",              VERSION,
Packit 76ec6a
        "copyright",            "Copyright \xc2\xa9 2001-2004 Kevin Vandersloot\n"
Packit 76ec6a
                                "Copyright \xc2\xa9 2005-2007 Benoît Dejean\n"
Packit 76ec6a
                                "Copyright \xc2\xa9 2011 Chris Kühl",
Packit 76ec6a
        "logo-icon-name",       "utilities-system-monitor",
Packit 76ec6a
        "authors",              authors,
Packit 76ec6a
        "artists",              artists,
Packit 76ec6a
        "documenters",          documenters,
Packit 76ec6a
        "translator-credits",   _("translator-credits"),
Packit 76ec6a
        "license",              "GPL 2+",
Packit 76ec6a
        "wrap-license",         TRUE,
Packit 76ec6a
        NULL
Packit 76ec6a
        );
Packit 76ec6a
}
Packit 76ec6a
Packit 76ec6a
static void
Packit 76ec6a
on_activate_refresh (GSimpleAction *, GVariant *, gpointer data)
Packit 76ec6a
{
Packit 76ec6a
    GsmApplication *app = (GsmApplication *) data;
Packit 76ec6a
    proctable_update (app);
Packit 76ec6a
}
Packit 76ec6a
Packit 76ec6a
static void
Packit 76ec6a
kill_process_with_confirmation (GsmApplication *app, int signal) {
Packit 76ec6a
    gboolean kill_dialog = app->settings->get_boolean(GSM_SETTING_SHOW_KILL_DIALOG);
Packit 76ec6a
Packit 76ec6a
    if (kill_dialog)
Packit 76ec6a
        procdialog_create_kill_dialog (app, signal);
Packit 76ec6a
    else
Packit 76ec6a
        kill_process (app, signal);
Packit 76ec6a
}
Packit 76ec6a
Packit 76ec6a
static void
Packit 76ec6a
on_activate_send_signal (GSimpleAction *, GVariant *parameter, gpointer data)
Packit 76ec6a
{
Packit 76ec6a
    GsmApplication *app = (GsmApplication *) data;
Packit 76ec6a
Packit 76ec6a
    /* no confirmation */
Packit 76ec6a
    gint32 signal = g_variant_get_int32(parameter);
Packit 76ec6a
    switch (signal) {
Packit 76ec6a
        case SIGCONT:
Packit 76ec6a
            kill_process (app, signal);
Packit 76ec6a
            break;
Packit 76ec6a
        case SIGSTOP:
Packit 76ec6a
        case SIGTERM:
Packit 76ec6a
        case SIGKILL:
Packit 76ec6a
            kill_process_with_confirmation (app, signal);
Packit 76ec6a
            break;
Packit 76ec6a
    }
Packit 76ec6a
}
Packit 76ec6a
Packit 76ec6a
static void
Packit 76ec6a
on_activate_memory_maps (GSimpleAction *, GVariant *, gpointer data)
Packit 76ec6a
{
Packit 76ec6a
    GsmApplication *app = (GsmApplication *) data;
Packit 76ec6a
Packit 76ec6a
    create_memmaps_dialog (app);
Packit 76ec6a
}
Packit 76ec6a
Packit 76ec6a
static void
Packit 76ec6a
on_activate_open_files (GSimpleAction *, GVariant *, gpointer data)
Packit 76ec6a
{
Packit 76ec6a
    GsmApplication *app = (GsmApplication *) data;
Packit 76ec6a
Packit 76ec6a
    create_openfiles_dialog (app);
Packit 76ec6a
}
Packit 76ec6a
Packit 76ec6a
static void
Packit 76ec6a
on_activate_process_properties (GSimpleAction *, GVariant *, gpointer data)
Packit 76ec6a
{
Packit 76ec6a
    GsmApplication *app = (GsmApplication *) data;
Packit 76ec6a
Packit 76ec6a
    create_procproperties_dialog (app);
Packit 76ec6a
}
Packit 76ec6a
Packit 76ec6a
static void
Packit 76ec6a
on_activate_radio (GSimpleAction *action, GVariant *parameter, gpointer data)
Packit 76ec6a
{
Packit 76ec6a
    g_action_change_state (G_ACTION (action), parameter);
Packit 76ec6a
}
Packit 76ec6a
Packit 76ec6a
static void
Packit 76ec6a
on_activate_toggle (GSimpleAction *action, GVariant *parameter, gpointer data)
Packit 76ec6a
{
Packit 76ec6a
    GVariant *state = g_action_get_state (G_ACTION (action));
Packit 76ec6a
    g_action_change_state (G_ACTION (action), g_variant_new_boolean (!g_variant_get_boolean (state)));    
Packit 76ec6a
    g_variant_unref (state);
Packit 76ec6a
}
Packit 76ec6a
Packit 76ec6a
static void
Packit 76ec6a
on_activate_search (GSimpleAction *action, GVariant *parameter, gpointer data)
Packit 76ec6a
{
Packit 76ec6a
    GsmApplication *app = (GsmApplication *) data;
Packit 76ec6a
    GVariant *state = g_action_get_state (G_ACTION (action));
Packit 76ec6a
    gboolean is_search_shortcut = g_variant_get_boolean (parameter);
Packit 76ec6a
    gboolean is_search_bar = gtk_search_bar_get_search_mode (app->search_bar);
Packit 76ec6a
    gtk_widget_set_visible (GTK_WIDGET (app->search_bar), is_search_bar || is_search_shortcut);
Packit 76ec6a
    if (is_search_shortcut && is_search_bar) {
Packit 76ec6a
        gtk_widget_grab_focus (GTK_WIDGET (app->search_entry));
Packit 76ec6a
    } else {
Packit 76ec6a
        g_action_change_state (G_ACTION (action), g_variant_new_boolean (!g_variant_get_boolean (state)));
Packit 76ec6a
    }
Packit 76ec6a
    g_variant_unref (state);
Packit 76ec6a
}
Packit 76ec6a
Packit 76ec6a
static void
Packit 76ec6a
change_show_page_state (GSimpleAction *action, GVariant *state, gpointer data)
Packit 76ec6a
{
Packit 76ec6a
    GsmApplication *app = (GsmApplication *) data;
Packit 76ec6a
Packit 76ec6a
    auto state_var = Glib::wrap(state, true);
Packit 76ec6a
    g_simple_action_set_state (action, state);
Packit 76ec6a
    app->settings->set_value (GSM_SETTING_CURRENT_TAB, state_var);
Packit 76ec6a
}
Packit 76ec6a
Packit 76ec6a
static void
Packit 76ec6a
change_show_processes_state (GSimpleAction *action, GVariant *state, gpointer data)
Packit 76ec6a
{
Packit 76ec6a
    GsmApplication *app = (GsmApplication *) data;
Packit 76ec6a
Packit 76ec6a
    auto state_var = Glib::wrap(state, true);
Packit 76ec6a
    g_simple_action_set_state (action, state);
Packit 76ec6a
    app->settings->set_value (GSM_SETTING_SHOW_WHOSE_PROCESSES, state_var);
Packit 76ec6a
}
Packit 76ec6a
Packit 76ec6a
static void
Packit 76ec6a
change_show_dependencies_state (GSimpleAction *action, GVariant *state, gpointer data)
Packit 76ec6a
{
Packit 76ec6a
    GsmApplication *app = (GsmApplication *) data;
Packit 76ec6a
Packit 76ec6a
    auto state_var = Glib::wrap(state, true);
Packit 76ec6a
    g_simple_action_set_state (action, state);
Packit 76ec6a
    app->settings->set_value (GSM_SETTING_SHOW_DEPENDENCIES, state_var);
Packit 76ec6a
}
Packit 76ec6a
Packit 76ec6a
static void
Packit 76ec6a
on_activate_priority (GSimpleAction *action, GVariant *parameter, gpointer data)
Packit 76ec6a
{
Packit 76ec6a
    GsmApplication *app = (GsmApplication *) data;
Packit 76ec6a
Packit 76ec6a
    g_action_change_state (G_ACTION (action), parameter);
Packit 76ec6a
Packit 76ec6a
    const gint32 priority = g_variant_get_int32 (parameter);
Packit 76ec6a
    switch (priority) {
Packit 76ec6a
        case 32: 
Packit 76ec6a
            procdialog_create_renice_dialog (app);
Packit 76ec6a
            break;
Packit 76ec6a
        default:
Packit 76ec6a
            renice (app, priority);
Packit 76ec6a
            break;
Packit 76ec6a
    }
Packit 76ec6a
Packit 76ec6a
}
Packit 76ec6a
Packit 76ec6a
static void
Packit 76ec6a
change_priority_state (GSimpleAction *action, GVariant *state, gpointer data)
Packit 76ec6a
{
Packit 76ec6a
    g_simple_action_set_state (action, state);
Packit 76ec6a
}
Packit 76ec6a
Packit 76ec6a
void
Packit 76ec6a
update_page_activities (GsmApplication *app)
Packit 76ec6a
{
Packit 76ec6a
    const char *current_page = gtk_stack_get_visible_child_name (app->stack);
Packit 76ec6a
Packit 76ec6a
    if (strcmp (current_page, "processes") == 0) {
Packit 76ec6a
        GAction *search_action = g_action_map_lookup_action (G_ACTION_MAP (app->main_window),
Packit 76ec6a
                                                             "search");
Packit 76ec6a
        proctable_update (app);
Packit 76ec6a
        proctable_thaw (app);
Packit 76ec6a
Packit 76ec6a
        gtk_widget_show (GTK_WIDGET (app->end_process_button));
Packit 76ec6a
        gtk_widget_show (GTK_WIDGET (app->search_button));
Packit 76ec6a
        gtk_widget_show (GTK_WIDGET (app->process_menu_button));
Packit 76ec6a
Packit 76ec6a
        update_sensitivity (app);
Packit 76ec6a
Packit 76ec6a
        if (g_variant_get_boolean (g_action_get_state (search_action)))
Packit 76ec6a
            gtk_widget_grab_focus (GTK_WIDGET (app->search_entry));
Packit 76ec6a
        else
Packit 76ec6a
            gtk_widget_grab_focus (GTK_WIDGET (app->tree));
Packit 76ec6a
    } else {
Packit 76ec6a
        proctable_freeze (app);
Packit 76ec6a
Packit 76ec6a
        gtk_widget_hide (GTK_WIDGET (app->end_process_button));
Packit 76ec6a
        gtk_widget_hide (GTK_WIDGET (app->search_button));
Packit 76ec6a
        gtk_widget_hide (GTK_WIDGET (app->process_menu_button));
Packit 76ec6a
Packit 76ec6a
        update_sensitivity (app);
Packit 76ec6a
    }
Packit 76ec6a
Packit 76ec6a
    if (strcmp (current_page, "resources") == 0) {
Packit 76ec6a
        load_graph_start (app->cpu_graph);
Packit 76ec6a
        load_graph_start (app->mem_graph);
Packit 76ec6a
        load_graph_start (app->net_graph);
Packit 76ec6a
    } else {
Packit 76ec6a
        load_graph_stop (app->cpu_graph);
Packit 76ec6a
        load_graph_stop (app->mem_graph);
Packit 76ec6a
        load_graph_stop (app->net_graph);
Packit 76ec6a
    }
Packit 76ec6a
Packit 76ec6a
    if (strcmp (current_page, "disks") == 0) {
Packit 76ec6a
        disks_update (app);
Packit 76ec6a
        disks_thaw (app);
Packit 76ec6a
    } else {
Packit 76ec6a
        disks_freeze (app);
Packit 76ec6a
    }
Packit 76ec6a
}
Packit 76ec6a
Packit 76ec6a
static void
Packit 76ec6a
cb_change_current_page (GtkStack *stack, GParamSpec *pspec, gpointer data)
Packit 76ec6a
{
Packit 76ec6a
    update_page_activities ((GsmApplication *)data);
Packit 76ec6a
}
Packit 76ec6a
Packit 76ec6a
static gboolean
Packit 76ec6a
cb_main_window_delete (GtkWidget *window, GdkEvent *event, gpointer data)
Packit 76ec6a
{
Packit 76ec6a
    GsmApplication *app = (GsmApplication *) data;
Packit 76ec6a
Packit 76ec6a
    app->shutdown ();
Packit 76ec6a
Packit 76ec6a
    return TRUE;
Packit 76ec6a
}
Packit 76ec6a
Packit 76ec6a
static gboolean
Packit 76ec6a
cb_main_window_state_changed (GtkWidget *window, GdkEventWindowState *event, gpointer data)
Packit 76ec6a
{
Packit 76ec6a
    GsmApplication *app = (GsmApplication *) data;
Packit 76ec6a
    auto current_page = app->settings->get_string (GSM_SETTING_CURRENT_TAB);
Packit 76ec6a
    if (event->new_window_state & GDK_WINDOW_STATE_BELOW ||
Packit 76ec6a
        event->new_window_state & GDK_WINDOW_STATE_ICONIFIED ||
Packit 76ec6a
        event->new_window_state & GDK_WINDOW_STATE_WITHDRAWN)
Packit 76ec6a
    {
Packit 76ec6a
        if (current_page == "processes") {
Packit 76ec6a
            proctable_freeze (app);
Packit 76ec6a
        } else if (current_page == "resources") {
Packit 76ec6a
            load_graph_stop (app->cpu_graph);
Packit 76ec6a
            load_graph_stop (app->mem_graph);
Packit 76ec6a
            load_graph_stop (app->net_graph);
Packit 76ec6a
        } else if (current_page == "disks") {
Packit 76ec6a
            disks_freeze (app);
Packit 76ec6a
        }
Packit 76ec6a
    } else  {
Packit 76ec6a
        if (current_page == "processes") {
Packit 76ec6a
            proctable_update (app);
Packit 76ec6a
            proctable_thaw (app);
Packit 76ec6a
        } else if (current_page == "resources") {
Packit 76ec6a
            load_graph_start (app->cpu_graph);
Packit 76ec6a
            load_graph_start (app->mem_graph);
Packit 76ec6a
            load_graph_start (app->net_graph);
Packit 76ec6a
        } else if (current_page == "disks") {
Packit 76ec6a
            disks_update (app);
Packit 76ec6a
            disks_thaw (app);
Packit 76ec6a
        }
Packit 76ec6a
    }
Packit 76ec6a
    return FALSE;
Packit 76ec6a
}
Packit 76ec6a
Packit 76ec6a
void
Packit 76ec6a
create_main_window (GsmApplication *app)
Packit 76ec6a
{
Packit 76ec6a
    GtkApplicationWindow *main_window;
Packit 76ec6a
    GtkStack *stack;
Packit 76ec6a
    GtkMenuButton *process_menu_button;
Packit 76ec6a
    GMenuModel *process_menu_model;
Packit 76ec6a
    GdkDisplay *display;
Packit 76ec6a
    GdkMonitor *monitor;
Packit 76ec6a
    GdkRectangle monitor_geometry;
Packit 76ec6a
    const char* session;
Packit 76ec6a
Packit 76ec6a
    int width, height, xpos, ypos;
Packit 76ec6a
Packit 76ec6a
    GtkBuilder *builder = gtk_builder_new();
Packit 76ec6a
    gtk_builder_add_from_resource (builder, "/org/gnome/gnome-system-monitor/data/interface.ui", NULL);
Packit 76ec6a
    gtk_builder_add_from_resource (builder, "/org/gnome/gnome-system-monitor/data/menus.ui", NULL);
Packit 76ec6a
Packit 76ec6a
    main_window = GTK_APPLICATION_WINDOW (gtk_builder_get_object (builder, "main_window"));
Packit 76ec6a
    gtk_window_set_application (GTK_WINDOW (main_window), app->gobj());
Packit 76ec6a
    gtk_widget_set_name (GTK_WIDGET (main_window), "gnome-system-monitor");
Packit 76ec6a
    app->main_window = main_window;
Packit 76ec6a
Packit 76ec6a
    session = g_getenv ("XDG_CURRENT_DESKTOP");
Packit 76ec6a
    if (session && !strstr (session, "GNOME")){
Packit 76ec6a
        GtkBox *mainbox;
Packit 76ec6a
        GtkHeaderBar *headerbar;
Packit 76ec6a
Packit 76ec6a
        mainbox = GTK_BOX (gtk_builder_get_object (builder, "main_box"));
Packit 76ec6a
        headerbar = GTK_HEADER_BAR (gtk_builder_get_object (builder, "header_bar"));
Packit 76ec6a
        gtk_style_context_remove_class (gtk_widget_get_style_context (GTK_WIDGET (headerbar)), "titlebar");
Packit 76ec6a
        gtk_window_set_titlebar (GTK_WINDOW (main_window), NULL);
Packit 76ec6a
        gtk_header_bar_set_show_close_button (headerbar, FALSE);
Packit 76ec6a
        gtk_box_pack_start (mainbox, GTK_WIDGET (headerbar), FALSE, FALSE, 0);
Packit 76ec6a
    }
Packit 76ec6a
Packit 76ec6a
    g_settings_get (app->settings->gobj(), GSM_SETTING_WINDOW_STATE, "(iiii)",
Packit 76ec6a
                    &width, &height, &xpos, &ypos);
Packit 76ec6a
    
Packit 76ec6a
    display = gdk_display_get_default ();
Packit 76ec6a
    monitor = gdk_display_get_monitor_at_point (display, xpos, ypos);
Packit 76ec6a
    if (monitor == NULL) {
Packit 76ec6a
        monitor = gdk_display_get_monitor (display, 0);
Packit 76ec6a
    }
Packit 76ec6a
    gdk_monitor_get_geometry (monitor, &monitor_geometry);
Packit 76ec6a
Packit 76ec6a
    width = CLAMP (width, 50, monitor_geometry.width);
Packit 76ec6a
    height = CLAMP (height, 50, monitor_geometry.height);
Packit 76ec6a
    xpos = CLAMP (xpos, 0, monitor_geometry.width - width);
Packit 76ec6a
    ypos = CLAMP (ypos, 0, monitor_geometry.height - height);
Packit 76ec6a
Packit 76ec6a
    gtk_window_set_default_size (GTK_WINDOW (main_window), width, height);
Packit 76ec6a
    gtk_window_move (GTK_WINDOW (main_window), xpos, ypos);
Packit 76ec6a
    if (app->settings->get_boolean (GSM_SETTING_MAXIMIZED))
Packit 76ec6a
        gtk_window_maximize (GTK_WINDOW (main_window));
Packit 76ec6a
Packit 76ec6a
    app->process_menu_button = process_menu_button = GTK_MENU_BUTTON (gtk_builder_get_object (builder, "process_menu_button"));
Packit 76ec6a
    process_menu_model = G_MENU_MODEL (gtk_builder_get_object (builder, "process-window-menu"));
Packit 76ec6a
    gtk_menu_button_set_menu_model (process_menu_button, process_menu_model);
Packit 76ec6a
Packit 76ec6a
    app->end_process_button = GTK_BUTTON (gtk_builder_get_object (builder, "end_process_button"));
Packit 76ec6a
Packit 76ec6a
    app->search_button = GTK_BUTTON (gtk_builder_get_object (builder, "search_button"));
Packit 76ec6a
Packit 76ec6a
    GActionEntry win_action_entries[] = {
Packit 76ec6a
        { "about", on_activate_about, NULL, NULL, NULL },
Packit 76ec6a
        { "search", on_activate_search, "b", "false", NULL },
Packit 76ec6a
        { "send-signal-stop", on_activate_send_signal, "i", NULL, NULL },
Packit 76ec6a
        { "send-signal-cont", on_activate_send_signal, "i", NULL, NULL },
Packit 76ec6a
        { "send-signal-end", on_activate_send_signal, "i", NULL, NULL },
Packit 76ec6a
        { "send-signal-kill", on_activate_send_signal, "i", NULL, NULL },
Packit 76ec6a
        { "priority", on_activate_priority, "i", "@i 0", change_priority_state },
Packit 76ec6a
        { "memory-maps", on_activate_memory_maps, NULL, NULL, NULL },
Packit 76ec6a
        { "open-files", on_activate_open_files, NULL, NULL, NULL },
Packit 76ec6a
        { "process-properties", on_activate_process_properties, NULL, NULL, NULL },
Packit 76ec6a
        { "refresh", on_activate_refresh, NULL, NULL, NULL },
Packit 76ec6a
        { "show-page", on_activate_radio, "s", "'resources'", change_show_page_state },
Packit 76ec6a
        { "show-whose-processes", on_activate_radio, "s", "'all'", change_show_processes_state },
Packit 76ec6a
        { "show-dependencies", on_activate_toggle, NULL, "false", change_show_dependencies_state }
Packit 76ec6a
    };
Packit 76ec6a
Packit 76ec6a
    g_action_map_add_action_entries (G_ACTION_MAP (main_window),
Packit 76ec6a
                                     win_action_entries,
Packit 76ec6a
                                     G_N_ELEMENTS (win_action_entries),
Packit 76ec6a
                                     app);
Packit 76ec6a
Packit 76ec6a
    GdkScreen* screen = gtk_widget_get_screen(GTK_WIDGET (main_window));
Packit 76ec6a
    GdkVisual* visual = gdk_screen_get_rgba_visual(screen);
Packit 76ec6a
Packit 76ec6a
    /* use visual, if available */
Packit 76ec6a
    if (visual)
Packit 76ec6a
        gtk_widget_set_visual(GTK_WIDGET (main_window), visual);
Packit 76ec6a
Packit 76ec6a
    /* create the main stack */
Packit 76ec6a
    app->stack = stack = GTK_STACK (gtk_builder_get_object (builder, "stack"));
Packit 76ec6a
Packit 76ec6a
    create_proc_view(app, builder);
Packit 76ec6a
Packit 76ec6a
    create_sys_view (app, builder);
Packit 76ec6a
    
Packit 76ec6a
    create_disk_view (app, builder);
Packit 76ec6a
Packit 76ec6a
    g_settings_bind (app->settings->gobj (), GSM_SETTING_CURRENT_TAB, stack, "visible-child-name", G_SETTINGS_BIND_DEFAULT);
Packit 76ec6a
Packit 76ec6a
    g_signal_connect (G_OBJECT (stack), "notify::visible-child",
Packit 76ec6a
                      G_CALLBACK (cb_change_current_page), app);
Packit 76ec6a
Packit 76ec6a
    g_signal_connect (G_OBJECT (main_window), "delete_event",
Packit 76ec6a
                      G_CALLBACK (cb_main_window_delete),
Packit 76ec6a
                      app);
Packit 76ec6a
    g_signal_connect (G_OBJECT (main_window), "window-state-event",
Packit 76ec6a
                      G_CALLBACK (cb_main_window_state_changed),
Packit 76ec6a
                      app);
Packit 76ec6a
Packit 76ec6a
    GAction *action;
Packit 76ec6a
    action = g_action_map_lookup_action (G_ACTION_MAP (main_window),
Packit 76ec6a
                                         "show-dependencies");
Packit 76ec6a
    g_action_change_state (action,
Packit 76ec6a
                           g_settings_get_value (app->settings->gobj (), GSM_SETTING_SHOW_DEPENDENCIES));
Packit 76ec6a
Packit 76ec6a
Packit 76ec6a
    action = g_action_map_lookup_action (G_ACTION_MAP (main_window),
Packit 76ec6a
                                         "show-whose-processes");
Packit 76ec6a
    g_action_change_state (action,
Packit 76ec6a
                           g_settings_get_value (app->settings->gobj (), GSM_SETTING_SHOW_WHOSE_PROCESSES));
Packit 76ec6a
Packit 76ec6a
    gtk_widget_show (GTK_WIDGET (main_window));
Packit 76ec6a
    
Packit 76ec6a
    update_page_activities (app);
Packit 76ec6a
Packit 76ec6a
    g_object_unref (G_OBJECT (builder));
Packit 76ec6a
}
Packit 76ec6a
Packit 76ec6a
gboolean
Packit 76ec6a
scroll_to_selection (gpointer data)
Packit 76ec6a
{
Packit 76ec6a
    GsmApplication *app = (GsmApplication *) data;
Packit 76ec6a
    GList* paths = gtk_tree_selection_get_selected_rows (app->selection, NULL);
Packit 76ec6a
    guint length = g_list_length(paths);
Packit 76ec6a
    if (length > 0) {
Packit 76ec6a
        GtkTreePath* last_path = (GtkTreePath*) g_list_nth_data(paths, length - 1);
Packit 76ec6a
        gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW (app->tree), last_path, NULL, FALSE, 0.0, 0.0);
Packit 76ec6a
    }
Packit 76ec6a
Packit 76ec6a
    g_list_free_full (paths, (GDestroyNotify) gtk_tree_path_free);
Packit 76ec6a
    return FALSE;
Packit 76ec6a
}
Packit 76ec6a
Packit 76ec6a
void
Packit 76ec6a
update_sensitivity(GsmApplication *app)
Packit 76ec6a
{
Packit 76ec6a
    const char * const selected_actions[] = { "send-signal-stop",
Packit 76ec6a
                                              "send-signal-cont",
Packit 76ec6a
                                              "send-signal-end",
Packit 76ec6a
                                              "send-signal-kill",
Packit 76ec6a
                                              "priority",
Packit 76ec6a
                                              "memory-maps",
Packit 76ec6a
                                              "open-files",
Packit 76ec6a
                                              "process-properties" };
Packit 76ec6a
Packit 76ec6a
    const char * const processes_actions[] = { "refresh",
Packit 76ec6a
                                               "search",
Packit 76ec6a
                                               "show-whose-processes",
Packit 76ec6a
                                               "show-dependencies" };
Packit 76ec6a
Packit 76ec6a
    size_t i;
Packit 76ec6a
    gboolean processes_sensitivity, selected_sensitivity;
Packit 76ec6a
    GAction *action;
Packit 76ec6a
Packit 76ec6a
    processes_sensitivity = (strcmp (gtk_stack_get_visible_child_name (GTK_STACK (app->stack)), "processes") == 0);
Packit 76ec6a
    selected_sensitivity = gtk_tree_selection_count_selected_rows (app->selection) > 0;
Packit 76ec6a
Packit 76ec6a
    for (i = 0; i != G_N_ELEMENTS (processes_actions); ++i) {
Packit 76ec6a
        action = g_action_map_lookup_action (G_ACTION_MAP (app->main_window),
Packit 76ec6a
                                             processes_actions[i]);
Packit 76ec6a
        g_simple_action_set_enabled (G_SIMPLE_ACTION (action),
Packit 76ec6a
                                     processes_sensitivity);
Packit 76ec6a
    }
Packit 76ec6a
Packit 76ec6a
    for (i = 0; i != G_N_ELEMENTS (selected_actions); ++i) {
Packit 76ec6a
        action = g_action_map_lookup_action (G_ACTION_MAP (app->main_window),
Packit 76ec6a
                                             selected_actions[i]);
Packit 76ec6a
        g_simple_action_set_enabled (G_SIMPLE_ACTION (action),
Packit 76ec6a
                                     processes_sensitivity & selected_sensitivity);
Packit 76ec6a
    }
Packit 76ec6a
Packit 76ec6a
    gtk_revealer_set_reveal_child (GTK_REVEALER (app->proc_actionbar_revealer),
Packit 76ec6a
                                   selected_sensitivity);
Packit 76ec6a
Packit 76ec6a
    // Scrolls the table to selected row. Useful when the last row is obstructed by the revealer
Packit 76ec6a
    guint duration_ms = gtk_revealer_get_transition_duration (GTK_REVEALER (app->proc_actionbar_revealer));
Packit 76ec6a
    g_timeout_add (duration_ms, scroll_to_selection, app);
Packit 76ec6a
}
Packit 76ec6a