无法在GTK3中使用gdk_test_simulate_button的问题 [英] Problem with not working gdk_test_simulate_button in GTK3

查看:94
本文介绍了无法在GTK3中使用gdk_test_simulate_button的问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

无法使gdk_test_simulate_button工作.有人可以帮助我,错误在哪里?

Can't get gdk_test_simulate_button working. Could someone help me, where is the error?

  1. 按下鼠标右键.
  2. 计时器启动.
  3. 经过计时器后,将模拟左键按下.

#include <stdio.h>
#include <gdk/gdkx.h>
#include <gtk/gtk.h>

int x_root = 0;
int y_root = 0;

gboolean simulate_left_button(gpointer user_data) {
  GdkWindow* gdkwindow = gtk_widget_get_window(user_data);
  Display* display = GDK_WINDOW_XDISPLAY(gdkwindow);
  Window window = GDK_WINDOW_XID(gdkwindow);
  Window root = DefaultRootWindow(display);
  Window subwindow = None;
  int x = 0, y = 0;

  XTranslateCoordinates(display, root, window, x_root, y_root, &x, &y,
    &subwindow);

  printf("XID: 0x%08lx\n", window);
  printf("x_root = %d, y_root = %d\n", x_root, y_root);
  printf("x = %d, y = %d\n", x, y);
  
  if (!gdk_test_simulate_button(gdkwindow, x, y, 1, GDK_BUTTON1_MASK,
      GDK_BUTTON_PRESS)) {
    fprintf(stderr, "gdk_test_simulate_button()\n");
  }
  return FALSE;
}

gboolean on_button_press (GtkWidget* widget, GdkEventButton* event,
    GdkWindowEdge edge) {
  if (event->type != GDK_BUTTON_PRESS)
    return TRUE;

  if (event->button == 3) {
    printf("Right XID: 0x%08lx\n", GDK_WINDOW_XID(gtk_widget_get_window(widget)));
    printf("Right x = %f, y = %f\n", event->x_root, event->y_root);

    x_root = event->x_root;
    y_root = event->y_root;
    g_timeout_add(1000, simulate_left_button, widget);
  } else if (event->button == 1) {
    printf("Left XID: 0x%08lx\n", GDK_WINDOW_XID(gtk_widget_get_window(widget)));
    printf("Left x = %f, y = %f\n", event->x_root, event->y_root);
  } else {
    printf("Unknown x = %f, y = %f\n", event->x_root, event->y_root);
  }
  return FALSE;
}

int main(int argc, char* argv[]) {
  GtkWidget* window = NULL;

  gtk_init(&argc, &argv);

  window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
  gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
  gtk_window_set_default_size(GTK_WINDOW(window), 230, 150);
  gtk_window_set_title(GTK_WINDOW(window), "Simulate Left button");
  gtk_window_set_decorated(GTK_WINDOW (window), FALSE);
  gtk_widget_add_events(window, GDK_BUTTON_PRESS_MASK);

  g_signal_connect(G_OBJECT(window), "button-press-event",
      G_CALLBACK(on_button_press), NULL);

  g_signal_connect_swapped(G_OBJECT(window), "destroy",
      G_CALLBACK(gtk_main_quit), G_OBJECT(window));

  gtk_widget_show(window);

  gtk_main();

  return 0;
}

// Build command: clang -Wall -g `pkg-config --cflags --libs gtk+-3.0` -lX11 test.c

在左上角窗口边缘附近按下鼠标右键并经过1秒后的实际输出:

The actual output when the right mouse button pressed near the top left window edge and 1 second elapsed:

Right XID: 0x03c00003
Right x = 817.465820, y = 410.487183
XID: 0x03c00003
x_root = 817, y_root = 410
x = 4, y = 6

经过1秒钟后的预期输出:

Expected output after 1 second elapsed:

Right XID: 0x03c00003
Right x = 817.465820, y = 410.487183
XID: 0x03c00003
x_root = 817, y_root = 410
x = 4, y = 6
Left XID: 0x03c00003   <-- These lines are missing above, "button-press-event" signal not raised.
Left x = 817, y = 410  <--

使用命令构建时,它在GTK2中运行良好

It is working well in GTK2 when built with the command

clang -Wall -g `pkg-config --cflags --libs gtk+-2.0` -lX11 test.c

推荐答案

我通过使用函数 gdk_event_put 代替了 gdk_test_simulate_button 来解决了这个问题.

I solved it with using the function gdk_event_put instead of gdk_test_simulate_button.

gboolean simulate_left_button(gpointer user_data) {
  GdkWindow* gdkwindow = gtk_widget_get_window(user_data);
  GdkDisplay* gdkdisplay = gdk_display_get_default();
  GdkDeviceManager* device_manager = gdk_display_get_device_manager(gdkdisplay);
  Display *display = GDK_WINDOW_XDISPLAY(gdkwindow);
  Window window = GDK_WINDOW_XID(gdkwindow);
  Window root = DefaultRootWindow(display);
  Window subwindow = None;
  GdkEvent* event = NULL;
  GdkEventButton* event_button = NULL;
  int x = 0, y = 0;

  XTranslateCoordinates(display, root, window, x_root, y_root, &x, &y,
    &subwindow);

  printf("XID: 0x%08lx\n", window);
  printf("x_root = %d, y_root = %d\n", x_root, y_root);
  printf("x = %d, y = %d\n", x, y);

  event = gdk_event_new(GDK_BUTTON_PRESS);
  event_button = &event->button;
  event_button->type = GDK_BUTTON_PRESS;
  event_button->window = gdkwindow;
  event_button->send_event = 1;
  event_button->time = GDK_CURRENT_TIME;
  event_button->x = x;
  event_button->y = y;
  event_button->state = GDK_BUTTON1_MASK;
  event_button->button = 1;
  event_button->device = gdk_device_manager_get_client_pointer(device_manager);
  event_button->x_root = x_root;
  event_button->y_root = y_root;

  gdk_event_put(event);
  gdk_event_free(event);
  return FALSE;
}

这篇关于无法在GTK3中使用gdk_test_simulate_button的问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆