From 9b6d8e63db85c30007b463e91f91a791969fa83f Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sat, 27 Apr 2024 16:36:24 +0200 Subject: Adding upstream version 1:3.38.4. Signed-off-by: Daniel Baumann --- panels/mouse/cc-mouse-caps-helper.c | 148 ++ panels/mouse/cc-mouse-caps-helper.h | 33 + panels/mouse/cc-mouse-panel.c | 452 ++++++ panels/mouse/cc-mouse-panel.h | 30 + panels/mouse/cc-mouse-panel.ui | 752 ++++++++++ panels/mouse/cc-mouse-test.c | 383 +++++ panels/mouse/cc-mouse-test.h | 32 + panels/mouse/cc-mouse-test.ui | 104 ++ panels/mouse/gnome-mouse-panel.desktop.in.in | 18 + panels/mouse/meson.build | 69 + panels/mouse/mouse.gresource.xml | 9 + panels/mouse/scroll-test-gegl.svg | 1781 +++++++++++++++++++++++ panels/mouse/scroll-test.svg | 1960 ++++++++++++++++++++++++++ panels/mouse/test-gnome-mouse-test.c | 33 + 14 files changed, 5804 insertions(+) create mode 100644 panels/mouse/cc-mouse-caps-helper.c create mode 100644 panels/mouse/cc-mouse-caps-helper.h create mode 100644 panels/mouse/cc-mouse-panel.c create mode 100644 panels/mouse/cc-mouse-panel.h create mode 100644 panels/mouse/cc-mouse-panel.ui create mode 100644 panels/mouse/cc-mouse-test.c create mode 100644 panels/mouse/cc-mouse-test.h create mode 100644 panels/mouse/cc-mouse-test.ui create mode 100644 panels/mouse/gnome-mouse-panel.desktop.in.in create mode 100644 panels/mouse/meson.build create mode 100644 panels/mouse/mouse.gresource.xml create mode 100644 panels/mouse/scroll-test-gegl.svg create mode 100644 panels/mouse/scroll-test.svg create mode 100644 panels/mouse/test-gnome-mouse-test.c (limited to 'panels/mouse') diff --git a/panels/mouse/cc-mouse-caps-helper.c b/panels/mouse/cc-mouse-caps-helper.c new file mode 100644 index 0000000..69546b2 --- /dev/null +++ b/panels/mouse/cc-mouse-caps-helper.c @@ -0,0 +1,148 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright 2015 Red Hat, Inc, + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * + * Author: Felipe Borges + */ + +#include +#include +#include + +#include "cc-mouse-caps-helper.h" + +static gboolean +touchpad_check_capabilities_x11 (gboolean *have_two_finger_scrolling, + gboolean *have_edge_scrolling, + gboolean *have_tap_to_click) +{ + GdkDisplay *gdisplay; + Display *display; + g_autoptr(GList) devicelist = NULL; + GList *l; + Atom realtype, prop_scroll_methods, prop_tapping_enabled; + int realformat; + unsigned long nitems, bytes_after; + unsigned char *data; + + gdisplay = gdk_display_get_default (); + display = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()); + prop_scroll_methods = XInternAtom (display, "libinput Scroll Methods Available", False); + prop_tapping_enabled = XInternAtom (display, "libinput Tapping Enabled", False); + if (!prop_scroll_methods || !prop_tapping_enabled) + return FALSE; + + *have_two_finger_scrolling = FALSE; + *have_edge_scrolling = FALSE; + *have_tap_to_click = FALSE; + + gdk_x11_display_error_trap_push (gdisplay); + + devicelist = gdk_seat_get_slaves (gdk_display_get_default_seat (gdk_display_get_default ()), + GDK_SEAT_CAPABILITY_ALL_POINTING); + for (l = devicelist; l != NULL; l = l->next) { + GdkDevice *device = l->data; + if (gdk_device_get_source (device) != GDK_SOURCE_TOUCHPAD) + continue; + + /* xorg-x11-drv-libinput */ + if ((XIGetProperty (display, gdk_x11_device_get_id (device), prop_scroll_methods, + 0, 2, False, XA_INTEGER, &realtype, &realformat, &nitems, + &bytes_after, &data) == Success) && (realtype != None)) { + /* Property data is booleans for two-finger, edge, on-button scroll available. */ + + if (data[0]) + *have_two_finger_scrolling = TRUE; + + if (data[1]) + *have_edge_scrolling = TRUE; + + XFree (data); + } + + if ((XIGetProperty (display, gdk_x11_device_get_id (device), prop_tapping_enabled, + 0, 1, False, XA_INTEGER, &realtype, &realformat, &nitems, + &bytes_after, &data) == Success) && (realtype != None)) { + /* Property data is boolean for tapping enabled. */ + *have_tap_to_click = TRUE; + + XFree (data); + } + } + + gdk_x11_display_error_trap_pop_ignored (gdisplay); + + return TRUE; +} + +gboolean +cc_touchpad_check_capabilities (gboolean *have_two_finger_scrolling, + gboolean *have_edge_scrolling, + gboolean *have_tap_to_click) +{ + if (GDK_IS_X11_DISPLAY (gdk_display_get_default ())) + return touchpad_check_capabilities_x11 (have_two_finger_scrolling, + have_edge_scrolling, + have_tap_to_click); + /* else we unconditionally show all touchpad knobs */ + *have_two_finger_scrolling = TRUE; + *have_edge_scrolling = TRUE; + *have_tap_to_click = TRUE; + return FALSE; +} + +gboolean +cc_synaptics_check (void) +{ + GdkDisplay *gdisplay; + Display *display; + g_autoptr(GList) devicelist = NULL; + GList *l; + Atom prop, realtype; + int realformat; + unsigned long nitems, bytes_after; + unsigned char *data; + gboolean have_synaptics = FALSE; + + if (!GDK_IS_X11_DISPLAY (gdk_display_get_default ())) + return FALSE; + + gdisplay = gdk_display_get_default (); + display = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()); + prop = XInternAtom (display, "Synaptics Capabilities", False); + + gdk_x11_display_error_trap_push (gdisplay); + + devicelist = gdk_seat_get_slaves (gdk_display_get_default_seat (gdk_display_get_default ()), + GDK_SEAT_CAPABILITY_ALL_POINTING); + for (l = devicelist; l != NULL; l = l->next) { + GdkDevice *device = l->data; + + if ((XIGetProperty (display, gdk_x11_device_get_id (device), prop, + 0, 2, False, XA_INTEGER, &realtype, &realformat, &nitems, + &bytes_after, &data) == Success) && (realtype != None)) { + have_synaptics = TRUE; + XFree (data); + } + + if (have_synaptics) + break; + } + + gdk_x11_display_error_trap_pop_ignored (gdisplay); + + return have_synaptics; +} diff --git a/panels/mouse/cc-mouse-caps-helper.h b/panels/mouse/cc-mouse-caps-helper.h new file mode 100644 index 0000000..93d9082 --- /dev/null +++ b/panels/mouse/cc-mouse-caps-helper.h @@ -0,0 +1,33 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- + * + * Copyright 2015 Red Hat, Inc, + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * + * Author: Felipe Borges + */ + +#pragma once + +#include + +G_BEGIN_DECLS + +gboolean cc_touchpad_check_capabilities (gboolean *have_two_finger_scrolling, + gboolean *have_edge_scrolling, + gboolean *have_tap_to_click); + +gboolean cc_synaptics_check (void); + +G_END_DECLS diff --git a/panels/mouse/cc-mouse-panel.c b/panels/mouse/cc-mouse-panel.c new file mode 100644 index 0000000..a7f018b --- /dev/null +++ b/panels/mouse/cc-mouse-panel.c @@ -0,0 +1,452 @@ +/* + * Copyright (C) 2010 Intel, Inc + * Copyright (C) 2012 Red Hat, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * + * Authors: Thomas Wood + * Rodrigo Moya + * Ondrej Holy + * + */ + +#include +#include + +#include "cc-mouse-caps-helper.h" +#include "cc-mouse-panel.h" +#include "cc-mouse-resources.h" +#include "cc-mouse-test.h" +#include "gsd-device-manager.h" +#include "gsd-input-helper.h" +#include "list-box-helper.h" + +struct _CcMousePanel +{ + CcPanel parent_instance; + + GtkListBoxRow *edge_scrolling_row; + GtkSwitch *edge_scrolling_switch; + GtkListBox *general_listbox; + GtkFrame *mouse_frame; + GtkListBox *mouse_listbox; + GtkSwitch *mouse_natural_scrolling_switch; + GtkScale *mouse_speed_scale; + CcMouseTest *mouse_test; + GtkRadioButton *primary_button_left; + GtkRadioButton *primary_button_right; + GtkScrolledWindow *scrolled_window; + GtkStack *stack; + GtkListBoxRow *tap_to_click_row; + GtkSwitch *tap_to_click_switch; + GtkButton *test_button; + GtkFrame *touchpad_frame; + GtkListBox *touchpad_listbox; + GtkListBoxRow *touchpad_natural_scrolling_row; + GtkSwitch *touchpad_natural_scrolling_switch; + GtkListBoxRow *touchpad_speed_row; + GtkScale *touchpad_speed_scale; + GtkSwitch *touchpad_toggle_switch; + GtkListBoxRow *two_finger_scrolling_row; + GtkSwitch *two_finger_scrolling_switch; + + GSettings *mouse_settings; + GSettings *gsd_mouse_settings; + GSettings *touchpad_settings; + + gboolean have_mouse; + gboolean have_touchpad; + gboolean have_touchscreen; + gboolean have_synaptics; + + gboolean left_handed; + GtkGesture *left_gesture; + GtkGesture *right_gesture; +}; + +CC_PANEL_REGISTER (CcMousePanel, cc_mouse_panel) + +static void +setup_touchpad_options (CcMousePanel *self) +{ + gboolean edge_scroll_enabled; + gboolean two_finger_scroll_enabled; + gboolean have_two_finger_scrolling; + gboolean have_edge_scrolling; + gboolean have_tap_to_click; + + if (self->have_synaptics || !self->have_touchpad) { + gtk_widget_hide (GTK_WIDGET (self->touchpad_frame)); + return; + } + + cc_touchpad_check_capabilities (&have_two_finger_scrolling, &have_edge_scrolling, &have_tap_to_click); + + gtk_widget_show (GTK_WIDGET (self->touchpad_frame)); + + gtk_widget_set_visible (GTK_WIDGET (self->two_finger_scrolling_row), have_two_finger_scrolling); + gtk_widget_set_visible (GTK_WIDGET (self->edge_scrolling_row), have_edge_scrolling); + gtk_widget_set_visible (GTK_WIDGET (self->tap_to_click_row), have_tap_to_click); + + edge_scroll_enabled = g_settings_get_boolean (self->touchpad_settings, "edge-scrolling-enabled"); + two_finger_scroll_enabled = g_settings_get_boolean (self->touchpad_settings, "two-finger-scrolling-enabled"); + if (edge_scroll_enabled && two_finger_scroll_enabled) + { + /* You cunning user set both, but you can only have one set in that UI */ + gtk_switch_set_active (self->edge_scrolling_switch, FALSE); + } +} + +static void +two_finger_scrolling_changed_event (CcMousePanel *self, + gboolean state) +{ + /* Updating the setting will cause the "state" of the switch to be updated. */ + g_settings_set_boolean (self->touchpad_settings, "two-finger-scrolling-enabled", state); + + /* Disable edge scrolling if two-finger scrolling is enabled */ + if (state && gtk_widget_get_visible (GTK_WIDGET (self->edge_scrolling_row))) + gtk_switch_set_active (self->edge_scrolling_switch, FALSE); +} + +static void +edge_scrolling_changed_event (CcMousePanel *self, + gboolean state) +{ + /* Updating the setting will cause the "state" of the switch to be updated. */ + g_settings_set_boolean (self->touchpad_settings, "edge-scrolling-enabled", state); + + /* Disable two-finger scrolling if edge scrolling is enabled */ + if (state && gtk_widget_get_visible (GTK_WIDGET (self->two_finger_scrolling_row))) + gtk_switch_set_active (self->two_finger_scrolling_switch, FALSE); +} + +static gboolean +get_touchpad_enabled (GSettings *settings) +{ + GDesktopDeviceSendEvents send_events; + + send_events = g_settings_get_enum (settings, "send-events"); + + return send_events == G_DESKTOP_DEVICE_SEND_EVENTS_ENABLED; +} + +static gboolean +show_touchpad_enabling_switch (CcMousePanel *self) +{ + if (!self->have_touchpad) + return FALSE; + + g_debug ("Should we show the touchpad disable switch: have_mouse: %s have_touchscreen: %s\n", + self->have_mouse ? "true" : "false", + self->have_touchscreen ? "true" : "false"); + + /* Let's show the button when a mouse or touchscreen is present */ + if (self->have_mouse || self->have_touchscreen) + return TRUE; + + /* Let's also show when the touchpad is disabled. */ + if (!get_touchpad_enabled (self->touchpad_settings)) + return TRUE; + + return FALSE; +} + +static gboolean +touchpad_enabled_get_mapping (GValue *value, + GVariant *variant, + gpointer user_data) +{ + gboolean enabled; + + enabled = g_strcmp0 (g_variant_get_string (variant, NULL), "enabled") == 0; + g_value_set_boolean (value, enabled); + + return TRUE; +} + +static GVariant * +touchpad_enabled_set_mapping (const GValue *value, + const GVariantType *type, + gpointer user_data) +{ + gboolean enabled; + + enabled = g_value_get_boolean (value); + + return g_variant_new_string (enabled ? "enabled" : "disabled"); +} + +static void +handle_secondary_button (CcMousePanel *self, + GtkRadioButton *button, + GtkGesture *gesture) +{ + gtk_gesture_single_set_touch_only (GTK_GESTURE_SINGLE (gesture), FALSE); + gtk_gesture_single_set_exclusive (GTK_GESTURE_SINGLE (gesture), TRUE); + gtk_gesture_single_set_button (GTK_GESTURE_SINGLE (gesture), GDK_BUTTON_SECONDARY); + g_signal_connect_swapped (gesture, "pressed", G_CALLBACK (gtk_button_clicked), button); + gtk_event_controller_set_propagation_phase (GTK_EVENT_CONTROLLER (gesture), GTK_PHASE_BUBBLE); +} + +/* Set up the property editors in the dialog. */ +static void +setup_dialog (CcMousePanel *self) +{ + GtkRadioButton *button; + + self->left_handed = g_settings_get_boolean (self->mouse_settings, "left-handed"); + button = self->left_handed ? self->primary_button_right : self->primary_button_left; + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE); + + g_settings_bind (self->mouse_settings, "left-handed", + self->primary_button_left, "active", + G_SETTINGS_BIND_DEFAULT | G_SETTINGS_BIND_INVERT_BOOLEAN); + g_settings_bind (self->mouse_settings, "left-handed", + self->primary_button_right, "active", + G_SETTINGS_BIND_DEFAULT); + + /* Allow changing orientation with either button */ + button = self->primary_button_right; + self->right_gesture = gtk_gesture_multi_press_new (GTK_WIDGET (button)); + handle_secondary_button (self, button, self->right_gesture); + button = self->primary_button_left; + self->left_gesture = gtk_gesture_multi_press_new (GTK_WIDGET (button)); + handle_secondary_button (self, button, self->left_gesture); + + g_settings_bind (self->mouse_settings, "natural-scroll", + self->mouse_natural_scrolling_switch, "active", + G_SETTINGS_BIND_DEFAULT); + + gtk_list_box_set_header_func (self->general_listbox, cc_list_box_update_header_func, NULL, NULL); + gtk_list_box_set_header_func (self->touchpad_listbox, cc_list_box_update_header_func, NULL, NULL); + + /* Mouse section */ + gtk_widget_set_visible (GTK_WIDGET (self->mouse_frame), self->have_mouse); + + g_settings_bind (self->mouse_settings, "speed", + gtk_range_get_adjustment (GTK_RANGE (self->mouse_speed_scale)), "value", + G_SETTINGS_BIND_DEFAULT); + + gtk_list_box_set_header_func (self->mouse_listbox, cc_list_box_update_header_func, NULL, NULL); + + /* Touchpad section */ + gtk_widget_set_visible (GTK_WIDGET (self->touchpad_toggle_switch), show_touchpad_enabling_switch (self)); + + g_settings_bind_with_mapping (self->touchpad_settings, "send-events", + self->touchpad_toggle_switch, "active", + G_SETTINGS_BIND_DEFAULT, + touchpad_enabled_get_mapping, + touchpad_enabled_set_mapping, + NULL, NULL); + g_settings_bind_with_mapping (self->touchpad_settings, "send-events", + self->touchpad_natural_scrolling_row, "sensitive", + G_SETTINGS_BIND_GET, + touchpad_enabled_get_mapping, + touchpad_enabled_set_mapping, + NULL, NULL); + g_settings_bind_with_mapping (self->touchpad_settings, "send-events", + self->touchpad_speed_row, "sensitive", + G_SETTINGS_BIND_GET, + touchpad_enabled_get_mapping, + touchpad_enabled_set_mapping, + NULL, NULL); + g_settings_bind_with_mapping (self->touchpad_settings, "send-events", + self->tap_to_click_row, "sensitive", + G_SETTINGS_BIND_GET, + touchpad_enabled_get_mapping, + touchpad_enabled_set_mapping, + NULL, NULL); + g_settings_bind_with_mapping (self->touchpad_settings, "send-events", + self->two_finger_scrolling_row, "sensitive", + G_SETTINGS_BIND_GET, + touchpad_enabled_get_mapping, + touchpad_enabled_set_mapping, + NULL, NULL); + g_settings_bind_with_mapping (self->touchpad_settings, "send-events", + self->edge_scrolling_row, "sensitive", + G_SETTINGS_BIND_GET, + touchpad_enabled_get_mapping, + touchpad_enabled_set_mapping, + NULL, NULL); + + g_settings_bind (self->touchpad_settings, "natural-scroll", + self->touchpad_natural_scrolling_switch, "active", + G_SETTINGS_BIND_DEFAULT); + + g_settings_bind (self->touchpad_settings, "speed", + gtk_range_get_adjustment (GTK_RANGE (self->touchpad_speed_scale)), "value", + G_SETTINGS_BIND_DEFAULT); + + g_settings_bind (self->touchpad_settings, "tap-to-click", + self->tap_to_click_switch, "active", + G_SETTINGS_BIND_DEFAULT); + + g_settings_bind (self->touchpad_settings, "two-finger-scrolling-enabled", + self->two_finger_scrolling_switch, "state", + G_SETTINGS_BIND_GET); + + g_settings_bind (self->touchpad_settings, "edge-scrolling-enabled", + self->edge_scrolling_switch, "state", + G_SETTINGS_BIND_GET); + + setup_touchpad_options (self); +} + +/* Callback issued when a button is clicked on the dialog */ +static void +device_changed (CcMousePanel *self) +{ + self->have_touchpad = touchpad_is_present (); + + setup_touchpad_options (self); + + self->have_mouse = mouse_is_present (); + gtk_widget_set_visible (GTK_WIDGET (self->mouse_frame), self->have_mouse); + gtk_widget_set_visible (GTK_WIDGET (self->touchpad_toggle_switch), show_touchpad_enabling_switch (self)); +} + +static void +on_content_size_changed (CcMousePanel *self, + GtkAllocation *allocation) +{ + if (allocation->height < 490) + { + gtk_scrolled_window_set_policy (self->scrolled_window, + GTK_POLICY_NEVER, GTK_POLICY_NEVER); + } + else + { + gtk_scrolled_window_set_policy (self->scrolled_window, + GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); + gtk_scrolled_window_set_min_content_height (self->scrolled_window, 490); + } +} + +static void +cc_mouse_panel_dispose (GObject *object) +{ + CcMousePanel *self = CC_MOUSE_PANEL (object); + + g_clear_object (&self->mouse_settings); + g_clear_object (&self->gsd_mouse_settings); + g_clear_object (&self->touchpad_settings); + g_clear_object (&self->right_gesture); + g_clear_object (&self->left_gesture); + + G_OBJECT_CLASS (cc_mouse_panel_parent_class)->dispose (object); +} + +static const char * +cc_mouse_panel_get_help_uri (CcPanel *panel) +{ + return "help:gnome-help/mouse"; +} + +static void +test_button_toggled_cb (CcMousePanel *self) +{ + if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (self->test_button))) + gtk_stack_set_visible_child (self->stack, GTK_WIDGET (self->mouse_test)); + else + gtk_stack_set_visible_child (self->stack, GTK_WIDGET (self->scrolled_window)); +} + +static void +cc_mouse_panel_constructed (GObject *object) +{ + CcMousePanel *self = CC_MOUSE_PANEL (object); + CcShell *shell; + + G_OBJECT_CLASS (cc_mouse_panel_parent_class)->constructed (object); + + /* Add test area button to shell header. */ + shell = cc_panel_get_shell (CC_PANEL (self)); + cc_shell_embed_widget_in_header (shell, GTK_WIDGET (self->test_button), GTK_POS_RIGHT); +} + +static void +cc_mouse_panel_init (CcMousePanel *self) +{ + GsdDeviceManager *device_manager; + + g_resources_register (cc_mouse_get_resource ()); + + cc_mouse_test_get_type (); + gtk_widget_init_template (GTK_WIDGET (self)); + + self->mouse_settings = g_settings_new ("org.gnome.desktop.peripherals.mouse"); + self->gsd_mouse_settings = g_settings_new ("org.gnome.settings-daemon.peripherals.mouse"); + self->touchpad_settings = g_settings_new ("org.gnome.desktop.peripherals.touchpad"); + + device_manager = gsd_device_manager_get (); + g_signal_connect_object (device_manager, "device-added", + G_CALLBACK (device_changed), self, G_CONNECT_SWAPPED); + g_signal_connect_object (device_manager, "device-removed", + G_CALLBACK (device_changed), self, G_CONNECT_SWAPPED); + + self->have_mouse = mouse_is_present (); + self->have_touchpad = touchpad_is_present (); + self->have_touchscreen = touchscreen_is_present (); + self->have_synaptics = cc_synaptics_check (); + if (self->have_synaptics) + g_warning ("Detected synaptics X driver, please migrate to libinput"); + + setup_dialog (self); +} + +static void +cc_mouse_panel_class_init (CcMousePanelClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); + CcPanelClass *panel_class = CC_PANEL_CLASS (klass); + + panel_class->get_help_uri = cc_mouse_panel_get_help_uri; + + object_class->dispose = cc_mouse_panel_dispose; + object_class->constructed = cc_mouse_panel_constructed; + + gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/control-center/mouse/cc-mouse-panel.ui"); + + gtk_widget_class_bind_template_child (widget_class, CcMousePanel, edge_scrolling_row); + gtk_widget_class_bind_template_child (widget_class, CcMousePanel, edge_scrolling_switch); + gtk_widget_class_bind_template_child (widget_class, CcMousePanel, general_listbox); + gtk_widget_class_bind_template_child (widget_class, CcMousePanel, mouse_frame); + gtk_widget_class_bind_template_child (widget_class, CcMousePanel, mouse_listbox); + gtk_widget_class_bind_template_child (widget_class, CcMousePanel, mouse_natural_scrolling_switch); + gtk_widget_class_bind_template_child (widget_class, CcMousePanel, mouse_speed_scale); + gtk_widget_class_bind_template_child (widget_class, CcMousePanel, mouse_test); + gtk_widget_class_bind_template_child (widget_class, CcMousePanel, primary_button_left); + gtk_widget_class_bind_template_child (widget_class, CcMousePanel, primary_button_right); + gtk_widget_class_bind_template_child (widget_class, CcMousePanel, scrolled_window); + gtk_widget_class_bind_template_child (widget_class, CcMousePanel, stack); + gtk_widget_class_bind_template_child (widget_class, CcMousePanel, tap_to_click_row); + gtk_widget_class_bind_template_child (widget_class, CcMousePanel, tap_to_click_switch); + gtk_widget_class_bind_template_child (widget_class, CcMousePanel, test_button); + gtk_widget_class_bind_template_child (widget_class, CcMousePanel, touchpad_frame); + gtk_widget_class_bind_template_child (widget_class, CcMousePanel, touchpad_listbox); + gtk_widget_class_bind_template_child (widget_class, CcMousePanel, touchpad_natural_scrolling_row); + gtk_widget_class_bind_template_child (widget_class, CcMousePanel, touchpad_natural_scrolling_switch); + gtk_widget_class_bind_template_child (widget_class, CcMousePanel, touchpad_speed_row); + gtk_widget_class_bind_template_child (widget_class, CcMousePanel, touchpad_speed_scale); + gtk_widget_class_bind_template_child (widget_class, CcMousePanel, touchpad_toggle_switch); + gtk_widget_class_bind_template_child (widget_class, CcMousePanel, two_finger_scrolling_row); + gtk_widget_class_bind_template_child (widget_class, CcMousePanel, two_finger_scrolling_switch); + + gtk_widget_class_bind_template_callback (widget_class, edge_scrolling_changed_event); + gtk_widget_class_bind_template_callback (widget_class, on_content_size_changed); + gtk_widget_class_bind_template_callback (widget_class, test_button_toggled_cb); + gtk_widget_class_bind_template_callback (widget_class, two_finger_scrolling_changed_event); +} diff --git a/panels/mouse/cc-mouse-panel.h b/panels/mouse/cc-mouse-panel.h new file mode 100644 index 0000000..ae83e8e --- /dev/null +++ b/panels/mouse/cc-mouse-panel.h @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2010 Intel, Inc + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * + * Author: Thomas Wood + * + */ + +#pragma once + +#include + +G_BEGIN_DECLS + +#define CC_TYPE_MOUSE_PANEL (cc_mouse_panel_get_type ()) +G_DECLARE_FINAL_TYPE (CcMousePanel, cc_mouse_panel, CC, MOUSE_PANEL, CcPanel) + +G_END_DECLS diff --git a/panels/mouse/cc-mouse-panel.ui b/panels/mouse/cc-mouse-panel.ui new file mode 100644 index 0000000..bcfde6d --- /dev/null +++ b/panels/mouse/cc-mouse-panel.ui @@ -0,0 +1,752 @@ + + + + + + True + True + center + Test Your _Settings + + + + + -1 + 1 + + + -1 + 1 + + + vertical + + + + + + + + + + + + horizontal + + + + + + diff --git a/panels/mouse/cc-mouse-test.c b/panels/mouse/cc-mouse-test.c new file mode 100644 index 0000000..35f337d --- /dev/null +++ b/panels/mouse/cc-mouse-test.c @@ -0,0 +1,383 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- + * + * Copyright (C) 2012 Red Hat, Inc. + * + * Written by: Ondrej Holy , + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#include + +#include +#include +#include +#include +#include +#include + +#include "cc-mouse-test.h" + +#include +#include + +/* Click test button sizes. */ +#define SHADOW_SIZE (10.0 / 180 * size) +#define SHADOW_SHIFT_Y (-1.0 / 180 * size) +#define SHADOW_OPACITY (0.15 / 180 * size) +#define OUTER_CIRCLE_SIZE (22.0 / 180 * size) +#define ANNULUS_SIZE (6.0 / 180 * size) +#define INNER_CIRCLE_SIZE (52.0 / 180 * size) + +static void setup_information_label (CcMouseTest *self); +static void setup_scroll_image (CcMouseTest *self); + +enum +{ + DOUBLE_CLICK_TEST_OFF, + DOUBLE_CLICK_TEST_MAYBE, + DOUBLE_CLICK_TEST_ON, + DOUBLE_CLICK_TEST_STILL_ON, + DOUBLE_CLICK_TEST_ALMOST_THERE, + DOUBLE_CLICK_TEST_GEGL +}; + +struct _CcMouseTest +{ + GtkBin parent_instance; + + GtkWidget *button_drawing_area; + GtkWidget *information_label; + GtkWidget *image; + GtkWidget *scrolled_window_adjustment; + GtkWidget *viewport; + + guint32 double_click_timestamp; + gint double_click_state; + gint button_state; + + GSettings *mouse_settings; + + gint information_label_timeout_id; + gint button_drawing_area_timeout_id; + gint scroll_image_timeout_id; +}; + +G_DEFINE_TYPE (CcMouseTest, cc_mouse_test, GTK_TYPE_BIN); + +/* Timeout for the double click test */ + +static gboolean +test_maybe_timeout (CcMouseTest *self) +{ + self->double_click_state = DOUBLE_CLICK_TEST_OFF; + + gtk_widget_queue_draw (self->button_drawing_area); + + self->button_drawing_area_timeout_id = 0; + + return FALSE; +} + +/* Timeout for the information label */ + +static gboolean +information_label_timeout (CcMouseTest *self) +{ + setup_information_label (self); + + self->information_label_timeout_id = 0; + + return FALSE; +} + +/* Timeout for the scroll image */ + +static gboolean +scroll_image_timeout (CcMouseTest *self) +{ + setup_scroll_image (self); + + self->scroll_image_timeout_id = 0; + + return FALSE; +} + +/* Set information label */ + +static void +setup_information_label (CcMouseTest *self) +{ + const gchar *message = NULL; + g_autofree gchar *label_text = NULL; + gboolean double_click; + + if (self->information_label_timeout_id != 0) { + g_source_remove (self->information_label_timeout_id); + self->information_label_timeout_id = 0; + } + + if (self->double_click_state == DOUBLE_CLICK_TEST_OFF) { + gtk_label_set_label (GTK_LABEL (self->information_label), _("Try clicking, double clicking, scrolling")); + return; + } + + if (self->double_click_state == DOUBLE_CLICK_TEST_GEGL) { + message = _("Five clicks, GEGL time!"), ""; + } else { + double_click = (self->double_click_state >= DOUBLE_CLICK_TEST_ON); + switch (self->button_state) { + case 1: + message = (double_click) ? _("Double click, primary button") : _("Single click, primary button"); + break; + case 2: + message = (double_click) ? _("Double click, middle button") : _("Single click, middle button"); + break; + case 3: + message = (double_click) ? _("Double click, secondary button") : _("Single click, secondary button"); + break; + } + } + + label_text = g_strconcat ("", message, "", NULL); + gtk_label_set_markup (GTK_LABEL (self->information_label), label_text); + + self->information_label_timeout_id = g_timeout_add (2500, (GSourceFunc) information_label_timeout, self); +} + +/* Update scroll image */ + +static void +setup_scroll_image (CcMouseTest *self) +{ + const char *resource; + + if (self->scroll_image_timeout_id != 0) { + g_source_remove (self->scroll_image_timeout_id); + self->scroll_image_timeout_id = 0; + } + + if (self->double_click_state == DOUBLE_CLICK_TEST_GEGL) + resource = "/org/gnome/control-center/mouse/scroll-test-gegl.svg"; + else + resource = "/org/gnome/control-center/mouse/scroll-test.svg"; + gtk_image_set_from_resource (GTK_IMAGE (self->image), resource); + + if (self->double_click_state != DOUBLE_CLICK_TEST_GEGL) + return; + + self->scroll_image_timeout_id = g_timeout_add (5000, (GSourceFunc) scroll_image_timeout, self); +} + +/* Callback issued when the user clicks the double click testing area. */ + +static gboolean +button_drawing_area_button_press_event (CcMouseTest *self, GdkEventButton *event) +{ + gint double_click_time; + + if (event->type != GDK_BUTTON_PRESS || event->button > 3) + return FALSE; + + double_click_time = g_settings_get_int (self->mouse_settings, "double-click"); + + if (self->button_drawing_area_timeout_id != 0) { + g_source_remove (self->button_drawing_area_timeout_id); + self->button_drawing_area_timeout_id = 0; + } + + /* Ignore fake double click using different buttons. */ + if (self->double_click_state != DOUBLE_CLICK_TEST_OFF && self->button_state != event->button) + self->double_click_state = DOUBLE_CLICK_TEST_OFF; + + switch (self->double_click_state) { + case DOUBLE_CLICK_TEST_OFF: + self->double_click_state = DOUBLE_CLICK_TEST_MAYBE; + self->button_drawing_area_timeout_id = g_timeout_add (double_click_time, (GSourceFunc) test_maybe_timeout, self); + break; + case DOUBLE_CLICK_TEST_MAYBE: + case DOUBLE_CLICK_TEST_ON: + case DOUBLE_CLICK_TEST_STILL_ON: + case DOUBLE_CLICK_TEST_ALMOST_THERE: + if (event->time - self->double_click_timestamp < double_click_time) { + self->double_click_state++; + self->button_drawing_area_timeout_id = g_timeout_add (2500, (GSourceFunc) test_maybe_timeout, self); + } else { + test_maybe_timeout (self); + } + break; + case DOUBLE_CLICK_TEST_GEGL: + self->double_click_state = DOUBLE_CLICK_TEST_OFF; + break; + } + + self->double_click_timestamp = event->time; + + gtk_widget_queue_draw (self->button_drawing_area); + + self->button_state = event->button; + setup_information_label (self); + setup_scroll_image (self); + + return TRUE; +} + +static gboolean +button_drawing_area_draw_event (CcMouseTest *self, + cairo_t *cr) +{ + gdouble center_x, center_y, size; + GdkRGBA inner_color, outer_color; + cairo_pattern_t *pattern; + + size = MAX (MIN (gtk_widget_get_allocated_width (self->button_drawing_area), gtk_widget_get_allocated_height (self->button_drawing_area)), 1); + center_x = gtk_widget_get_allocated_width (self->button_drawing_area) / 2.0; + center_y = gtk_widget_get_allocated_height (self->button_drawing_area) / 2.0; + + switch (self->double_click_state) { + case DOUBLE_CLICK_TEST_ON: + case DOUBLE_CLICK_TEST_STILL_ON: + case DOUBLE_CLICK_TEST_ALMOST_THERE: + case DOUBLE_CLICK_TEST_GEGL: + gdk_rgba_parse (&outer_color, "#729fcf"); + gdk_rgba_parse (&inner_color, "#729fcf"); + break; + case DOUBLE_CLICK_TEST_MAYBE: + gdk_rgba_parse (&outer_color, "#729fcf"); + gdk_rgba_parse (&inner_color, "#ffffff"); + break; + case DOUBLE_CLICK_TEST_OFF: + gdk_rgba_parse (&outer_color, "#ffffff"); + gdk_rgba_parse (&inner_color, "#ffffff"); + break; + } + + /* Draw shadow. */ + cairo_rectangle (cr, center_x - size / 2, center_y - size / 2, size, size); + pattern = cairo_pattern_create_radial (center_x, center_y, 0, center_x, center_y, size); + cairo_pattern_add_color_stop_rgba (pattern, 0.5 - SHADOW_SIZE / size, 0, 0, 0, SHADOW_OPACITY); + cairo_pattern_add_color_stop_rgba (pattern, 0.5, 0, 0, 0, 0); + cairo_set_source (cr, pattern); + cairo_fill (cr); + + /* Draw outer circle. */ + cairo_set_line_width (cr, OUTER_CIRCLE_SIZE); + cairo_arc (cr, center_x, center_y + SHADOW_SHIFT_Y, + INNER_CIRCLE_SIZE + ANNULUS_SIZE + OUTER_CIRCLE_SIZE / 2, + 0, 2 * G_PI); + gdk_cairo_set_source_rgba (cr, &outer_color); + cairo_stroke (cr); + + /* Draw inner circle. */ + cairo_set_line_width (cr, 0); + cairo_arc (cr, center_x, center_y + SHADOW_SHIFT_Y, + INNER_CIRCLE_SIZE, + 0, 2 * G_PI); + gdk_cairo_set_source_rgba (cr, &inner_color); + cairo_fill (cr); + + return FALSE; +} + +static void +setup_dialog (CcMouseTest *self) +{ + GtkAdjustment *adjustment; + GtkStyleProvider *provider; + + adjustment = GTK_ADJUSTMENT (self->scrolled_window_adjustment); + gtk_adjustment_set_value (adjustment, + gtk_adjustment_get_upper (adjustment)); + + provider = GTK_STYLE_PROVIDER (gtk_css_provider_new ()); + gtk_css_provider_load_from_data (GTK_CSS_PROVIDER (provider), "* {background: #565854}", -1, NULL); + gtk_style_context_add_provider (gtk_widget_get_style_context (self->viewport), + provider, + GTK_STYLE_PROVIDER_PRIORITY_APPLICATION); + gtk_style_context_add_provider (gtk_widget_get_style_context (self->button_drawing_area), + provider, + GTK_STYLE_PROVIDER_PRIORITY_APPLICATION); + g_object_unref (provider); +} + +static void +cc_mouse_test_finalize (GObject *object) +{ + CcMouseTest *self = CC_MOUSE_TEST (object); + + g_clear_object (&self->mouse_settings); + + if (self->information_label_timeout_id != 0) { + g_source_remove (self->information_label_timeout_id); + self->information_label_timeout_id = 0; + } + + if (self->scroll_image_timeout_id != 0) { + g_source_remove (self->scroll_image_timeout_id); + self->scroll_image_timeout_id = 0; + } + + if (self->button_drawing_area_timeout_id != 0) { + g_source_remove (self->button_drawing_area_timeout_id); + self->button_drawing_area_timeout_id = 0; + } + + G_OBJECT_CLASS (cc_mouse_test_parent_class)->finalize (object); +} + +static void +cc_mouse_test_class_init (CcMouseTestClass *klass) +{ + GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->finalize = cc_mouse_test_finalize; + + gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/control-center/mouse/cc-mouse-test.ui"); + + gtk_widget_class_bind_template_child (widget_class, CcMouseTest, button_drawing_area); + gtk_widget_class_bind_template_child (widget_class, CcMouseTest, information_label); + gtk_widget_class_bind_template_child (widget_class, CcMouseTest, image); + gtk_widget_class_bind_template_child (widget_class, CcMouseTest, scrolled_window_adjustment); + gtk_widget_class_bind_template_child (widget_class, CcMouseTest, viewport); + + gtk_widget_class_bind_template_callback (widget_class, button_drawing_area_button_press_event); + gtk_widget_class_bind_template_callback (widget_class, button_drawing_area_draw_event); +} + +static void +cc_mouse_test_init (CcMouseTest *self) +{ + g_autoptr(GError) error = NULL; + + gtk_widget_init_template (GTK_WIDGET (self)); + + self->double_click_timestamp = 0; + self->double_click_state = DOUBLE_CLICK_TEST_OFF; + self->button_state = 0; + + self->mouse_settings = g_settings_new ("org.gnome.settings-daemon.peripherals.mouse"); + + self->information_label_timeout_id = 0; + self->button_drawing_area_timeout_id = 0; + self->scroll_image_timeout_id = 0; + + setup_dialog (self); +} + +GtkWidget * +cc_mouse_test_new (void) +{ + return (GtkWidget *) g_object_new (CC_TYPE_MOUSE_TEST, NULL); +} diff --git a/panels/mouse/cc-mouse-test.h b/panels/mouse/cc-mouse-test.h new file mode 100644 index 0000000..eb2af1b --- /dev/null +++ b/panels/mouse/cc-mouse-test.h @@ -0,0 +1,32 @@ +/* -*- mode: c; style: linux -*- + * + * Copyright (C) 2012 Red Hat, Inc. + * + * Written by: Ondrej Holy + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#pragma once + +#include + +G_BEGIN_DECLS + +#define CC_TYPE_MOUSE_TEST (cc_mouse_test_get_type ()) +G_DECLARE_FINAL_TYPE (CcMouseTest, cc_mouse_test, CC, MOUSE_TEST, GtkBin) + +GtkWidget *cc_mouse_test_new (void); + +G_END_DECLS diff --git a/panels/mouse/cc-mouse-test.ui b/panels/mouse/cc-mouse-test.ui new file mode 100644 index 0000000..d547331 --- /dev/null +++ b/panels/mouse/cc-mouse-test.ui @@ -0,0 +1,104 @@ + + + + + 100 + 100 + 1 + 10 + + + diff --git a/panels/mouse/gnome-mouse-panel.desktop.in.in b/panels/mouse/gnome-mouse-panel.desktop.in.in new file mode 100644 index 0000000..53d23ec --- /dev/null +++ b/panels/mouse/gnome-mouse-panel.desktop.in.in @@ -0,0 +1,18 @@ +[Desktop Entry] +Name=Mouse & Touchpad +Comment=Change your mouse or touchpad sensitivity and select right or left-handed +Exec=gnome-control-center mouse +# Translators: Do NOT translate or transliterate this text (this is an icon file name)! +Icon=input-mouse +Terminal=false +Type=Application +NoDisplay=true +StartupNotify=true +Categories=GNOME;GTK;Settings;HardwareSettings;X-GNOME-Settings-Panel;X-GNOME-DevicesSettings; +OnlyShowIn=GNOME;Unity; +X-GNOME-Bugzilla-Bugzilla=GNOME +X-GNOME-Bugzilla-Product=gnome-control-center +X-GNOME-Bugzilla-Component=mouse +X-GNOME-Bugzilla-Version=@VERSION@ +# Translators: Search terms to find the Mouse and Touchpad panel. Do NOT translate or localize the semicolons! The list MUST also end with a semicolon! +Keywords=Trackpad;Pointer;Click;Tap;Double;Button;Trackball;Scroll; diff --git a/panels/mouse/meson.build b/panels/mouse/meson.build new file mode 100644 index 0000000..357aaae --- /dev/null +++ b/panels/mouse/meson.build @@ -0,0 +1,69 @@ +panels_list += cappletname +desktop = 'gnome-@0@-panel.desktop'.format(cappletname) + +desktop_in = configure_file( + input: desktop + '.in.in', + output: desktop + '.in', + configuration: desktop_conf +) + +i18n.merge_file( + desktop, + type: 'desktop', + input: desktop_in, + output: desktop, + po_dir: po_dir, + install: true, + install_dir: control_center_desktopdir +) + +resource_data = files( + 'cc-mouse-panel.ui', + 'cc-mouse-test.ui', + 'scroll-test-gegl.svg', + 'scroll-test.svg' +) + +common_sources = gnome.compile_resources( + 'cc-' + cappletname + '-resources', + cappletname + '.gresource.xml', + c_name: 'cc_' + cappletname, + dependencies: resource_data, + export: true +) + +sources = common_sources + files( + 'cc-mouse-panel.c', + 'cc-mouse-caps-helper.c', + 'cc-mouse-test.c', +) + +deps = common_deps + [ + gnome_settings_dep, + libdevice_dep, + x11_dep, + xi_dep +] + +panels_libs += static_library( + cappletname + '-properties', + sources: sources, + include_directories: top_inc, + dependencies: deps, + c_args: cflags +) + +test_name = 'test-gnome-mouse-test' + +sources = common_sources + files( + 'cc-mouse-test.c', + test_name + '.c' +) + +executable( + test_name, + sources, + include_directories: top_inc, + dependencies: deps, + c_args: cflags +) diff --git a/panels/mouse/mouse.gresource.xml b/panels/mouse/mouse.gresource.xml new file mode 100644 index 0000000..0568705 --- /dev/null +++ b/panels/mouse/mouse.gresource.xml @@ -0,0 +1,9 @@ + + + + cc-mouse-panel.ui + cc-mouse-test.ui + scroll-test.svg + scroll-test-gegl.svg + + diff --git a/panels/mouse/scroll-test-gegl.svg b/panels/mouse/scroll-test-gegl.svg new file mode 100644 index 0000000..eb3761d --- /dev/null +++ b/panels/mouse/scroll-test-gegl.svg @@ -0,0 +1,1781 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/panels/mouse/scroll-test.svg b/panels/mouse/scroll-test.svg new file mode 100644 index 0000000..73e933a --- /dev/null +++ b/panels/mouse/scroll-test.svg @@ -0,0 +1,1960 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/panels/mouse/test-gnome-mouse-test.c b/panels/mouse/test-gnome-mouse-test.c new file mode 100644 index 0000000..5b006f6 --- /dev/null +++ b/panels/mouse/test-gnome-mouse-test.c @@ -0,0 +1,33 @@ +#include +#include + +#include "cc-mouse-resources.h" +#include "cc-mouse-test.h" + +static gboolean +delete_event_cb (GtkWidget *widget, GdkEvent *event, gpointer user_data) +{ + gtk_main_quit (); + + return FALSE; +} + +int main (int argc, char **argv) +{ + GtkWidget *widget; + GtkWidget *window; + + gtk_init (&argc, &argv); + + window = gtk_window_new (GTK_WINDOW_TOPLEVEL); + gtk_widget_show (window); + widget = cc_mouse_test_new (); + gtk_widget_show (widget); + gtk_container_add (GTK_CONTAINER (window), widget); + + g_signal_connect (G_OBJECT (window), "delete-event", G_CALLBACK (delete_event_cb), NULL); + + gtk_main (); + + return 0; +} -- cgit v1.2.3