X-Git-Url: https://asedeno.scripts.mit.edu/gitweb/?a=blobdiff_plain;f=unix%2Fgtkask.c;h=c2b582e9c9afe29e29a2d0befaf5c6dd3453ecca;hb=095072fa46b2d7b8beafaddb2f873d2f500a1e10;hp=4ee1c8ed012dec5b136e687f21e549048ea87e13;hpb=afae35eb9085d0f0cdb3a1bd9737b120011ee93a;p=PuTTY.git diff --git a/unix/gtkask.c b/unix/gtkask.c index 4ee1c8ed..c2b582e9 100644 --- a/unix/gtkask.c +++ b/unix/gtkask.c @@ -16,6 +16,7 @@ #include "gtkfont.h" #include "gtkcompat.h" +#include "gtkmisc.h" #include "misc.h" @@ -42,6 +43,11 @@ struct askpass_ctx { #endif char *passphrase; int passlen, passsize; +#if GTK_CHECK_VERSION(3,20,0) + GdkSeat *seat; /* for gdk_seat_grab */ +#elif GTK_CHECK_VERSION(3,0,0) + GdkDevice *keyboard; /* for gdk_device_grab */ +#endif }; static void visually_acknowledge_keypress(struct askpass_ctx *ctx) @@ -212,8 +218,61 @@ static gint expose_area(GtkWidget *widget, GdkEventExpose *event, static int try_grab_keyboard(struct askpass_ctx *ctx) { - int ret = gdk_keyboard_grab(gtk_widget_get_window(ctx->dialog), - FALSE, GDK_CURRENT_TIME); + int ret; + +#if GTK_CHECK_VERSION(3,20,0) + /* + * Grabbing the keyboard in GTK 3.20 requires the new notion of + * GdkSeat. + */ + GdkSeat *seat; + + seat = gdk_display_get_default_seat + (gtk_widget_get_display(ctx->dialog)); + if (!seat) + return FALSE; + + ctx->seat = seat; + ret = gdk_seat_grab(seat, gtk_widget_get_window(ctx->dialog), + GDK_SEAT_CAPABILITY_KEYBOARD, + TRUE, NULL, NULL, NULL, NULL); +#elif GTK_CHECK_VERSION(3,0,0) + /* + * And it has to be done differently again prior to GTK 3.20. + */ + GdkDeviceManager *dm; + GdkDevice *pointer, *keyboard; + + dm = gdk_display_get_device_manager + (gtk_widget_get_display(ctx->dialog)); + if (!dm) + return FALSE; + + pointer = gdk_device_manager_get_client_pointer(dm); + if (!pointer) + return FALSE; + keyboard = gdk_device_get_associated_device(pointer); + if (!keyboard) + return FALSE; + if (gdk_device_get_source(keyboard) != GDK_SOURCE_KEYBOARD) + return FALSE; + + ctx->keyboard = keyboard; + ret = gdk_device_grab(ctx->keyboard, + gtk_widget_get_window(ctx->dialog), + GDK_OWNERSHIP_NONE, + TRUE, + GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK, + NULL, + GDK_CURRENT_TIME); +#else + /* + * It's much simpler in GTK 1 and 2! + */ + ret = gdk_keyboard_grab(gtk_widget_get_window(ctx->dialog), + FALSE, GDK_CURRENT_TIME); +#endif + return ret == GDK_GRAB_SUCCESS; } @@ -249,6 +308,7 @@ static const char *gtk_askpass_setup(struct askpass_ctx *ctx, const char *prompt_text) { int i; + GtkBox *action_area; ctx->passlen = 0; ctx->passsize = 2048; @@ -257,13 +317,18 @@ static const char *gtk_askpass_setup(struct askpass_ctx *ctx, /* * Create widgets. */ - ctx->dialog = gtk_dialog_new(); + ctx->dialog = our_dialog_new(); gtk_window_set_title(GTK_WINDOW(ctx->dialog), window_title); + gtk_window_set_position(GTK_WINDOW(ctx->dialog), GTK_WIN_POS_CENTER); ctx->promptlabel = gtk_label_new(prompt_text); + align_label_left(GTK_LABEL(ctx->promptlabel)); + gtk_widget_show(ctx->promptlabel); gtk_label_set_line_wrap(GTK_LABEL(ctx->promptlabel), TRUE); - gtk_container_add(GTK_CONTAINER(gtk_dialog_get_content_area - (GTK_DIALOG(ctx->dialog))), - ctx->promptlabel); +#if GTK_CHECK_VERSION(3,0,0) + gtk_label_set_width_chars(GTK_LABEL(ctx->promptlabel), 48); +#endif + our_dialog_add_to_content_area(GTK_WINDOW(ctx->dialog), + ctx->promptlabel, TRUE, TRUE, 0); #if GTK_CHECK_VERSION(2,0,0) ctx->imc = gtk_im_multicontext_new(); #endif @@ -279,6 +344,9 @@ static const char *gtk_askpass_setup(struct askpass_ctx *ctx, return "unable to allocate colours"; } #endif + + action_area = our_dialog_make_action_hbox(GTK_WINDOW(ctx->dialog)); + for (i = 0; i < N_DRAWING_AREAS; i++) { ctx->drawingareas[i].area = gtk_drawing_area_new(); #ifndef DRAW_DEFAULT_CAIRO @@ -290,9 +358,8 @@ static const char *gtk_askpass_setup(struct askpass_ctx *ctx, * context-sensitive way, like measuring the size of some * piece of template text. */ gtk_widget_set_size_request(ctx->drawingareas[i].area, 32, 32); - gtk_container_add(GTK_CONTAINER(gtk_dialog_get_action_area - (GTK_DIALOG(ctx->dialog))), - ctx->drawingareas[i].area); + gtk_box_pack_end(action_area, ctx->drawingareas[i].area, + TRUE, TRUE, 5); g_signal_connect(G_OBJECT(ctx->drawingareas[i].area), "configure_event", G_CALLBACK(configure_area), @@ -308,6 +375,12 @@ static const char *gtk_askpass_setup(struct askpass_ctx *ctx, G_CALLBACK(expose_area), &ctx->drawingareas[i]); #endif + +#if GTK_CHECK_VERSION(3,0,0) + g_object_set(G_OBJECT(ctx->drawingareas[i].area), + "margin-bottom", 8, (const char *)NULL); +#endif + gtk_widget_show(ctx->drawingareas[i].area); } ctx->active_area = rand() % N_DRAWING_AREAS; @@ -340,7 +413,7 @@ static const char *gtk_askpass_setup(struct askpass_ctx *ctx, /* * And now that we've got the keyboard grab, connect up our - * keyboard handlers, and display the prompt. + * keyboard handlers. */ #if GTK_CHECK_VERSION(2,0,0) g_signal_connect(G_OBJECT(ctx->imc), "commit", @@ -354,14 +427,19 @@ static const char *gtk_askpass_setup(struct askpass_ctx *ctx, gtk_im_context_set_client_window(ctx->imc, gtk_widget_get_window(ctx->dialog)); #endif - gtk_widget_show(ctx->promptlabel); return NULL; } static void gtk_askpass_cleanup(struct askpass_ctx *ctx) { +#if GTK_CHECK_VERSION(3,20,0) + gdk_seat_ungrab(ctx->seat); +#elif GTK_CHECK_VERSION(3,0,0) + gdk_device_ungrab(ctx->keyboard, GDK_CURRENT_TIME); +#else gdk_keyboard_ungrab(GDK_CURRENT_TIME); +#endif gtk_grab_remove(ctx->promptlabel); if (ctx->passphrase) { @@ -447,7 +525,7 @@ int main(int argc, char **argv) ret = dupprintf("usage: %s ", argv[0]); } else { srand(time(NULL)); - ret = gtk_askpass_main(argv[1], &success); + ret = gtk_askpass_main(NULL, "Enter passphrase", argv[1], &success); } if (!success) {