pnmixer
Volume mixer for the system tray
ui-hotkey-dialog.c
Go to the documentation of this file.
1 /* ui-hotkey-dialog.c
2  * PNmixer is written by Nick Lanham, a fork of OBmixer
3  * which was programmed by Lee Ferrett, derived
4  * from the program "AbsVolume" by Paul Sherman
5  * This program is free software; you can redistribute
6  * it and/or modify it under the terms of the GNU General
7  * Public License v3. source code is available at
8  * <http://github.com/nicklan/pnmixer>
9  */
10 
18 #ifdef HAVE_CONFIG_H
19 #include "config.h"
20 #endif
21 
22 #include <glib.h>
23 #include <gtk/gtk.h>
24 
25 #include "support-log.h"
26 #include "support-intl.h"
27 #include "support-ui.h"
28 #include "ui-hotkey-dialog.h"
29 
30 #include "main.h"
31 
32 #ifdef WITH_GTK3
33 #define HOTKEY_DIALOG_UI_FILE "hotkey-dialog-gtk3.glade"
34 #else
35 #define HOTKEY_DIALOG_UI_FILE "hotkey-dialog-gtk2.glade"
36 #endif
37 
38 /* Helpers */
39 
40 /* Configure the appearance of the hotkey dialog window. */
41 static void
42 configure_hotkey_dialog(GtkWindow *window, GtkLabel *instruction_label,
43  const gchar *hotkey)
44 {
45  gchar *title;
46  gchar *instruction;
47 
48  title = g_strdup_printf(_("Set %s HotKey"), hotkey);
49  gtk_window_set_title(window, title);
50  g_free(title);
51 
52  instruction = g_strdup_printf(_("Press new HotKey for <b>%s</b>"), hotkey);
53  gtk_label_set_markup(instruction_label, instruction);
54  g_free(instruction);
55 }
56 
57 /* Public functions & signal handlers */
58 
59 struct hotkey_dialog {
60  GtkWidget *hotkey_dialog;
61  GtkWidget *instruction_label;
62  GtkWidget *key_pressed_label;
63 };
64 
75 gboolean
76 on_hotkey_dialog_key_press_event(G_GNUC_UNUSED GtkWidget *widget,
77  GdkEventKey *event, HotkeyDialog *dialog)
78 {
79  GdkModifierType state, consumed;
80  GtkLabel *key_pressed_label;
81  gchar *key_text;
82  guint key_val;
83 
84  key_pressed_label = GTK_LABEL(dialog->key_pressed_label);
85 
86  state = event->state;
87  gdk_keymap_translate_keyboard_state(gdk_keymap_get_default(),
88  event->hardware_keycode,
89  state, event->group, &key_val,
90  NULL, NULL, &consumed);
91 
92  state &= ~consumed;
93  state &= gtk_accelerator_get_default_mod_mask();
94 
95  key_text = gtk_accelerator_name(key_val, state);
96  gtk_label_set_text(key_pressed_label, key_text);
97  g_free(key_text);
98 
99  return FALSE;
100 }
101 
112 gboolean
114  G_GNUC_UNUSED GdkEventKey *event,
115  G_GNUC_UNUSED HotkeyDialog *dialog)
116 {
117  gtk_dialog_response(GTK_DIALOG(widget), GTK_RESPONSE_OK);
118 
119  return FALSE;
120 }
121 
129 gchar *
131 {
132  GtkDialog *hotkey_dialog = GTK_DIALOG(dialog->hotkey_dialog);
133  GtkLabel *key_pressed_label = GTK_LABEL(dialog->key_pressed_label);
134  GdkWindow *window;
135  GdkGrabStatus grab_status;
136  gint resp;
137 
138  /* Show widget at first, otherwise the following calls fail */
139  gtk_widget_show_now(GTK_WIDGET(hotkey_dialog));
140 
141  /* Grab keyboard */
142 #ifdef WITH_GTK3
143  GdkDevice *device;
144 
145  device = gtk_get_current_event_device();
146  if (device == NULL) {
147  WARN("Couldn't get current device");
148  return NULL;
149  }
150 
151  window = gtk_widget_get_window(GTK_WIDGET(hotkey_dialog));
152 
153 #if GTK_CHECK_VERSION(3,20,0)
154  grab_status = gdk_seat_grab
155  (gdk_device_get_seat(device),
156  window,
157  GDK_SEAT_CAPABILITY_KEYBOARD, TRUE,
158  NULL, NULL, NULL, NULL);
159 #else
160  grab_status = gdk_device_grab
161  (device,
162  window,
163  GDK_OWNERSHIP_APPLICATION, TRUE,
164  GDK_KEY_PRESS_MASK, NULL, GDK_CURRENT_TIME);
165 #endif /* GTK_CHECK_VERSION(3,20,0) */
166 #else
167  window = gtk_widget_get_window(GTK_WIDGET(hotkey_dialog));
168 
169  grab_status = gdk_keyboard_grab
170  (window, TRUE, GDK_CURRENT_TIME);
171 #endif /* WITH_GTK3 */
172 
173  if (grab_status != GDK_GRAB_SUCCESS) {
174  run_error_dialog(_("Could not grab the keyboard."));
175  return NULL;
176  }
177 
178  /* Run the dialog */
179  resp = gtk_dialog_run(hotkey_dialog);
180 
181  /* Ungrab keyboard */
182 #ifdef WITH_GTK3
183 #if GTK_CHECK_VERSION(3,20,0)
184  gdk_seat_ungrab(gdk_device_get_seat(device));
185 #else
186  gdk_device_ungrab(device, GDK_CURRENT_TIME);
187 #endif /* GTK_CHECK_VERSION(3,20,0) */
188 #else
189  gdk_keyboard_ungrab(GDK_CURRENT_TIME);
190 #endif /* WITH_GTK3 */
191 
192  /* Handle response */
193  if (resp != GTK_RESPONSE_OK)
194  return NULL;
195 
196  /* Return the key entered */
197  return g_strdup(gtk_label_get_text(key_pressed_label));
198 }
199 
205 void
207 {
208  DEBUG("Destroying");
209 
210  gtk_widget_destroy(dialog->hotkey_dialog);
211  g_free(dialog);
212 }
213 
221 HotkeyDialog *
222 hotkey_dialog_create(GtkWindow *parent, const gchar *hotkey)
223 {
224  gchar *uifile;
225  GtkBuilder *builder;
226  HotkeyDialog *dialog;
227 
228  dialog = g_new0(HotkeyDialog, 1);
229 
230  /* Build UI file */
232  g_assert(uifile);
233 
234  DEBUG("Building from ui file '%s'", uifile);
235  builder = gtk_builder_new_from_file(uifile);
236 
237  /* Save some widgets for later use */
238  assign_gtk_widget(builder, dialog, hotkey_dialog);
239  assign_gtk_widget(builder, dialog, instruction_label);
240  assign_gtk_widget(builder, dialog, key_pressed_label);
241 
242  /* Configure some widgets */
243  configure_hotkey_dialog(GTK_WINDOW(dialog->hotkey_dialog),
244  GTK_LABEL(dialog->instruction_label),
245  hotkey);
246 
247  /* Set transient parent */
248  gtk_window_set_transient_for(GTK_WINDOW(dialog->hotkey_dialog), parent);
249 
250  /* Connect ui signal handlers */
251  gtk_builder_connect_signals(builder, dialog);
252 
253  /* Cleanup */
254  g_object_unref(builder);
255  g_free(uifile);
256 
257  return dialog;
258 }
GtkBuilder * gtk_builder_new_from_file(const gchar *filename)
Definition: support-ui.c:25
#define _(String)
Definition: support-intl.h:44
Internationalization support.
Logging support.
HotkeyDialog * hotkey_dialog_create(GtkWindow *parent, const gchar *hotkey)
static void configure_hotkey_dialog(GtkWindow *window, GtkLabel *instruction_label, const gchar *hotkey)
gchar * hotkey_dialog_run(HotkeyDialog *dialog)
Header for support-ui.c.
#define HOTKEY_DIALOG_UI_FILE
#define assign_gtk_widget(builder, container, name)
Definition: support-ui.h:75
Header for ui-hotkey-dialog.c.
GtkWidget * instruction_label
#define DEBUG(...)
Definition: support-log.h:38
Header for main.c.
gchar * get_ui_file(const char *filename)
Definition: support-ui.c:58
GtkWidget * hotkey_dialog
Definition: hotkey.h:22
void run_error_dialog(const char *fmt,...)
Definition: main.c:188
gboolean on_hotkey_dialog_key_press_event(G_GNUC_UNUSED GtkWidget *widget, GdkEventKey *event, HotkeyDialog *dialog)
gboolean on_hotkey_dialog_key_release_event(GtkWidget *widget, G_GNUC_UNUSED GdkEventKey *event, G_GNUC_UNUSED HotkeyDialog *dialog)
void hotkey_dialog_destroy(HotkeyDialog *dialog)
GtkWidget * key_pressed_label
#define WARN(...)
Definition: support-log.h:37