1

I'm running two fullscreen apps on two monitors on Ubuntu 16.10. app1 needs the pointer and must be focused all time, so I need to lock the pointer in app1.

I had written a tool to grab the pointer like this:

#include <stdio.h>
#include <X11/Xlib.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
Display *display;
XEvent xevent;
Window window;
int x,y;
void setPos(int x,int y){
  XWarpPointer(display,None,window,0,0,0,0,x,y);
  XFlush(display);
}
int main(int argc, char **argv){
  if( (display = XOpenDisplay(NULL)) == NULL )
    return -1;
  window = DefaultRootWindow(display);

  XAllowEvents(display, AsyncBoth, CurrentTime);
  XGrabPointer(display,window,0,PointerMotionMask,GrabModeAsync,GrabModeAsync,None,None,CurrentTime);
  while(1) {
    XNextEvent(display, &xevent);
    switch (xevent.type) {
        case MotionNotify:
          if(xevent.xmotion.x_root>1920){
             setPos(1920,xevent.xmotion.y_root);
          }
        break;
     }
  }
  return 0;
}

This tool can capture the pointer's event and limit the pointer stay in app1, but the pointer can't operate anything in app1. All pointer event except motion are not working. Is there any suggestion to the codes? Or any other idea to finish the work?

Ilya
  • 4,583
  • 4
  • 26
  • 51
user6731513
  • 21
  • 1
  • 5
  • Look at [`SendEvent()`](https://www.x.org/releases/X11R7.6/doc/libX11/specs/libX11/libX11.html#Sending_Events_to_Other_Applications) to send the event back. You might need to actually look up the target window. I'm way too rusty with X11 to post actual code, but this should be a good clue. Also, read the index of that manual, it has pretty good section titles ("Sending Events to Other Applications" in this case). – unwind Mar 07 '17 at 09:05
  • I used the method ,it didn't work ,nothing changed. XSendEvent(display,PointerWindow,True,ButtonPressMask,&xevent); the window which the pointer clicked was not actived,the terminal which I runned the tool was active all time. – user6731513 Mar 08 '17 at 09:01

1 Answers1

0

finally Xephyr has solved the problem. use this command to run Xephyr:

/usr/bin/Xephyr :1 -softCursor -name aaa -screen 1920x1080 -keybd   evdev,,device=/dev/input/eventkb,xkbrules=evdev,xkbmodel=evdev,xkblayout=us -mouse evdev,5,device=/dev/input/$eventmouse  -retro

Xephyr will start a new Display and grab the keyboard and mouse,then you can run your app in display :1.

btw: 1 the event number of keyboard and mouse maybe changed when you re plug the device,so make a shell script to run Xephey and get the event number in your script like this:

eventkb=`grep -A5 "pci0000:00/0000:00:14.0/usb2/2-5/2-5:1.0/0003:1A81:1007" /proc/bus/input/devices | grep 'H: Handlers=' | grep --only-matching -e 'event[0-9]*'`

2 if you don't want to run Xephyr by root,you will receive an error about permission to grab the keyboard and mouse. you can create file /etc/udev/rules.d/my.rules and put SUBSYSTEM=="input", OWNER="username", GROUP="usernamer" in it. then you can run Xephyr by username. maybe you need to relogin or restart.

user6731513
  • 21
  • 1
  • 5