static void hotkey_activated_cb (char *signature, gpointer user_data) { GtkHotkeyX11Listener *self; GtkHotkeyInfo *hotkey; GList *iter; guint event_time; g_return_if_fail (GTK_HOTKEY_IS_X11_LISTENER(user_data)); g_return_if_fail (signature != NULL); self = GTK_HOTKEY_X11_LISTENER(user_data); event_time = tomboy_keybinder_get_current_event_time (); /* Trigger signals for hotkeys with matching signature */ for (iter = self->priv->hotkeys; iter; iter = iter->next) { hotkey = GTK_HOTKEY_INFO (iter->data); if (g_str_equal (signature, gtk_hotkey_info_get_signature (hotkey))) { gtk_hotkey_listener_activated (GTK_HOTKEY_LISTENER(self), hotkey, event_time); gtk_hotkey_info_activated (hotkey, event_time); } } }
static void tomboy_window_override_user_time (GtkWindow *window) { #ifdef GDK_WINDOWING_X11 guint32 ev_time = gtk_get_current_event_time(); if (ev_time == 0) { /* * FIXME: Global keypresses use an event filter on the root * window, which processes events before GDK sees them. */ ev_time = tomboy_keybinder_get_current_event_time (); } if (ev_time == 0) { gint ev_mask = gtk_widget_get_events (GTK_WIDGET(window)); if (!(ev_mask & GDK_PROPERTY_CHANGE_MASK)) { gtk_widget_add_events (GTK_WIDGET (window), GDK_PROPERTY_CHANGE_MASK); } /* * NOTE: Last resort for D-BUS or other non-interactive * openings. Causes roundtrip to server. Lame. */ ev_time = gdk_x11_get_server_time (gtk_widget_get_window(GTK_WIDGET(window))); } TRACE (g_print("Setting _NET_WM_USER_TIME to: %d\n", ev_time)); gdk_x11_window_set_user_time (gtk_widget_get_window(GTK_WIDGET(window)), ev_time); #endif }
/* This function will make sure that tilda window becomes active (gains * the focus) when it is called. * * This has to be the worst possible way of making this work, but it was the * only way to get metacity to play nicely. All the other WM's are so nice, * why oh why does metacity hate us so? */ void tilda_window_set_active (tilda_window *tw) { DEBUG_FUNCTION ("tilda_window_set_active"); DEBUG_ASSERT (tw != NULL); Display *x11_display = GDK_WINDOW_XDISPLAY (gtk_widget_get_window (tw->window) ); Window x11_window = GDK_WINDOW_XID (gtk_widget_get_window (tw->window) ); Window x11_root_window = GDK_WINDOW_XID ( gtk_widget_get_root_window (tw->window) ); GdkScreen *screen = gtk_widget_get_screen (tw->window); XEvent event; long mask = SubstructureRedirectMask | SubstructureNotifyMask; if (gdk_x11_screen_supports_net_wm_hint (screen, gdk_atom_intern_static_string ("_NET_ACTIVE_WINDOW"))) { guint32 timestamp = gtk_get_current_event_time (); if (timestamp == 0) { timestamp = tomboy_keybinder_get_current_event_time (); } event.xclient.type = ClientMessage; event.xclient.serial = 0; event.xclient.send_event = True; event.xclient.display = x11_display; event.xclient.window = x11_window; event.xclient.message_type = gdk_x11_get_xatom_by_name ("_NET_ACTIVE_WINDOW"); event.xclient.format = 32; event.xclient.data.l[0] = 2; /* pager */ event.xclient.data.l[1] = timestamp; /* timestamp */ event.xclient.data.l[2] = 0; event.xclient.data.l[3] = 0; event.xclient.data.l[4] = 0; XSendEvent (x11_display, x11_root_window, False, mask, &event); } else { /* The WM doesn't support the EWMH standards. We'll print a warning and * try this, though it probably won't work... */ g_printerr ("WARNING: Window manager (%s) does not support EWMH hints\n", gdk_x11_screen_get_window_manager_name (screen)); XRaiseWindow (x11_display, x11_window); } }
/** * @force_hide: This option is used by the auto hide feature, so we can ignore the checks to focus tilda instead * of pulling up. */ void pull (struct tilda_window_ *tw, enum pull_state state, gboolean force_hide) { DEBUG_FUNCTION ("pull"); DEBUG_ASSERT (tw != NULL); DEBUG_ASSERT (state == PULL_UP || state == PULL_DOWN || state == PULL_TOGGLE); gint i; gboolean needsFocus = !tw->focus_loss_on_keypress && !gtk_window_is_active(GTK_WINDOW(tw->window)) && !force_hide && !tw->hide_non_focused; if (tw->current_state == DOWN && needsFocus) { /** * See tilda_window.c in focus_out_event_cb for an explanation about focus_loss_on_keypress * This conditional branch will only focus tilda but it does not actually pull the window up. */ TRACE (g_print("Tilda window not focused but visible\n")); gdk_x11_window_set_user_time(gtk_widget_get_window(tw->window), tomboy_keybinder_get_current_event_time()); tilda_window_set_active(tw); } else if (tw->current_state == UP && state != PULL_UP) { /* Keep things here just like they are. If you use gtk_window_present() here, you * will introduce some weird graphical glitches. Also, calling gtk_window_move() * before showing the window avoids yet more glitches. You should probably not use * gtk_window_show_all() here, as it takes a long time to execute. * * Overriding the user time here seems to work a lot better than calling * gtk_window_present_with_time() here, or at the end of the function. I have * no idea why, they should do the same thing. */ gdk_x11_window_set_user_time (gtk_widget_get_window (tw->window), tomboy_keybinder_get_current_event_time()); gtk_window_move (GTK_WINDOW(tw->window), config_getint ("x_pos"), config_getint ("y_pos")); gtk_widget_show (GTK_WIDGET(tw->window)); /* Nasty code to make metacity behave. Starting at metacity-2.22 they "fixed" the * focus stealing prevention to make the old _NET_WM_USER_TIME hack * not work anymore. This is working for now... */ tilda_window_set_active (tw); /* The window should maintain its properties when it is merely hidden, but it does * not. If you delete the following call, the window will not remain visible * on all workspaces after pull()ing it up and down a number of times. * * Note that the "Always on top" property doesn't seem to go away, only this * property (Show on all desktops) does... */ if (config_getbool ("pinned")) gtk_window_stick (GTK_WINDOW (tw->window)); if (config_getbool ("animation")) { for (i=0; i<16; i++) { gtk_window_move (GTK_WINDOW(tw->window), posIV[2][i], posIV[0][i]); gtk_window_resize (GTK_WINDOW(tw->window), posIV[3][i], posIV[1][i]); process_all_pending_gtk_events (); g_usleep (config_getint ("slide_sleep_usec")); } } debug_printf ("pull(): MOVED DOWN\n"); tw->current_state = DOWN; } else if (state != PULL_DOWN) { if (config_getbool ("animation")) { for (i=15; i>=0; i--) { gtk_window_move (GTK_WINDOW(tw->window), posIV[2][i], posIV[0][i]); gtk_window_resize (GTK_WINDOW(tw->window), posIV[3][i], posIV[1][i]); process_all_pending_gtk_events (); g_usleep (config_getint ("slide_sleep_usec")); } } /* All we have to do at this point is hide the window. * Case 1 - Animation on: The window has shrunk, just hide it * Case 2 - Animation off: Just hide the window */ gtk_widget_hide (GTK_WIDGET(tw->window)); debug_printf ("pull(): MOVED UP\n"); tw->current_state = UP; } }