int main(int argc, char* argv[]) { Display* display = XOpenDisplay(NULL); Window root = RootWindow(display, DefaultScreen(display)); // get active window Window active; int revert_to_return; XGetInputFocus(display, &active, &revert_to_return); active = get_toplevel_parent(display, active); // get mouse position Window window_returned; unsigned int mask_return; int root_x, root_y, win_x, win_y; XQueryPointer(display, root, &window_returned, &window_returned, &root_x, &root_y, &win_x, &win_y, &mask_return); // http://standards.freedesktop.org/wm-spec/1.3/ar01s04.html#id2522561 XClientMessageEvent evt; memset(&evt, 0, sizeof(evt)); evt.type = ClientMessage; evt.window = active; evt.message_type = XInternAtom(display, "_NET_WM_MOVERESIZE", False); evt.format = 32; evt.data.l[0] = root_x; evt.data.l[1] = root_y; evt.data.l[2] = 10; // _NET_WM_MOVERESIZE_MOVE_KEYBOARD; // http://standards.freedesktop.org/wm-spec/1.3/ar01s03.html XSendEvent(display, root, False, (SubstructureNotifyMask|SubstructureRedirectMask), (XEvent*)&evt); XCloseDisplay(display); return 0; }
int main(int argc, char* argv[]) { Display* display = XOpenDisplay(NULL); Window root = RootWindow(display, DefaultScreen(display)); // get active window Window active; int revert_to_return; XGetInputFocus(display, &active, &revert_to_return); active = get_toplevel_parent(display, active); // move mouse to the bottom border of the window XWindowAttributes windowattr; XGetWindowAttributes(display, active, &windowattr); XWarpPointer(display, None, active, 0, 0, 0, 0, windowattr.width, windowattr.height); // http://standards.freedesktop.org/wm-spec/1.3/ar01s04.html#id2522561 XClientMessageEvent evt; memset(&evt, 0, sizeof(evt)); evt.type = ClientMessage; evt.window = active; evt.message_type = XInternAtom(display, "_NET_WM_MOVERESIZE", False); evt.format = 32; evt.data.l[0] = windowattr.x + windowattr.width; evt.data.l[1] = windowattr.y + windowattr.height; evt.data.l[2] = 4; // _NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT // http://standards.freedesktop.org/wm-spec/1.3/ar01s03.html XSendEvent(display, root, False, (SubstructureNotifyMask|SubstructureRedirectMask), (XEvent*)&evt); XCloseDisplay(display); return 0; }
/* used for xinerama and pure xrandr modes */ void _al_xsys_get_active_window_center(ALLEGRO_SYSTEM_XGLX *s, int *x, int *y) { Window focus; int revert_to = 0; _al_mutex_lock(&s->lock); if (!XGetInputFocus(s->x11display, &focus, &revert_to)) { ALLEGRO_ERROR("XGetInputFocus failed!\n"); _al_mutex_unlock(&s->lock); return; } if (focus == None || focus == PointerRoot) { ALLEGRO_DEBUG("XGetInputFocus returned special window, selecting default root!\n"); focus = DefaultRootWindow(s->x11display); } else { /* this horribleness is due to toolkits like GTK (and probably Qt) creating * a 1x1 window under the window you're looking at that actually accepts * all input, so we need to grab the top level parent window rather than * whatever happens to have focus */ focus = get_toplevel_parent(s, focus); } ALLEGRO_DEBUG("XGetInputFocus returned %i\n", (int)focus); XWindowAttributes attr; if (XGetWindowAttributes(s->x11display, focus, &attr) == 0) { ALLEGRO_ERROR("XGetWindowAttributes failed :(\n"); _al_mutex_unlock(&s->lock); return; } _al_mutex_unlock(&s->lock); /* check the center of the window with focus * might be a bit more useful than just checking the top left */ ALLEGRO_DEBUG("focus geom: %ix%i %ix%i\n", attr.x, attr.y, attr.width, attr.height); *x = (attr.x + (attr.x + attr.width)) / 2; *y = (attr.y + (attr.y + attr.height)) / 2; }
int main(int argc, char *argv[]) { KeySym key; XEvent event; int hidden = 1; int fullscreen = 0; int i, tmp; int old_height = 0; Window tmpwin, last_focused, current_focused; XWindowAttributes wa; /* strip the path from argv[0] if there is one */ progname = strrchr(argv[0], '/'); if (!progname) progname = argv[0]; else progname++; for (i = 1; i < argc; i++) { if (!strcmp(argv[i], "-h")) { printf("%s:\n" "-e: program to execute\n" "you can configure me via xresources:\n" "%s*foo:value\n" "foo can be any standard xterm/urxvt/st xresource or:\n" "resource default value\n\n" "term: xterm\n" "restart: 0\n" "xOffset: 0\n" "yOffset: 0\n" "xrandrSupport: 0\n" "screenWidth: Display width\n" "consoleHeight: 10\n" "aniDelay: 40\n" "stepSize; 1\n" "toggleKey: ControlAlt+y\n" "keySmaller: Control+KP_Subtract\n" "keyBigger: Control+KP_Add\n" "keyFull: Alt+F11\n", progname, progname); exit(0); } } if (!(dpy = XOpenDisplay(NULL))) { fprintf(stderr, " can not open dpy %s", XDisplayName(NULL)); } screen = DefaultScreen(dpy); root = RootWindow(dpy, screen); XSetErrorHandler(handle_xerror); cursor = XCreateFontCursor(dpy, XC_double_arrow); get_defaults(); init_win(); init_command(argc, argv); init_xterm(1); while (1) { XNextEvent(dpy, &event); switch (event.type) { case FocusOut: /* Always keep input focus when visible */ if (!hidden) XSetInputFocus(dpy, termwin, RevertToPointerRoot, CurrentTime); break; case EnterNotify: XSetInputFocus(dpy, termwin, RevertToPointerRoot, CurrentTime); XSync(dpy, False); break; case LeaveNotify: if (last_focused && event.xcrossing.detail != NotifyInferior) { XSetInputFocus(dpy, last_focused, RevertToPointerRoot, CurrentTime); XSync(dpy, False); } break; case KeyPress: key = XKeycodeToKeysym(dpy, event.xkey.keycode, 0); if (key == opt_key) { if (!hidden) { XGetInputFocus(dpy, ¤t_focused, &revert_to); if (last_focused && current_focused == termwin) XSetInputFocus(dpy, last_focused, RevertToPointerRoot, CurrentTime); /* else XSetInputFocus(dpy, PointerRoot, RevertToPointerRoot, CurrentTime); */ if (opt_step && !fullscreen) roll(UP); XUnmapWindow(dpy, win); hidden = 1; XSync(dpy, False); } else { XGetInputFocus(dpy, &last_focused, &revert_to); last_focused = get_toplevel_parent(last_focused); if (opt_step && !fullscreen) { XGrabServer(dpy); roll(DOWN); XUngrabServer(dpy); } else if (opt_xrandr) update_geom(last_focused); XMoveWindow(dpy, win, opt_x, opt_y); XMapWindow(dpy, win); XRaiseWindow(dpy, win); XSetInputFocus(dpy, termwin, RevertToPointerRoot, CurrentTime); hidden = 0; XSync(dpy, False); XSetInputFocus(dpy, termwin, RevertToPointerRoot, CurrentTime); XSync(dpy, False); } break; } if (!hidden) { if (key == opt_key_full) { if (!fullscreen) { old_height = height; height = get_optimal_height(get_display_height()); fullscreen = 1; } else { height = old_height; fullscreen = 0; } } /* update height inc just in case something changed for the * terminal, i.e. font size */ resize_inc = get_height_inc(); if (key == opt_key_bigger) height += resize_inc; if (key == opt_key_smaller) height -= resize_inc; if (height < resize_inc) height = resize_inc; height = get_optimal_height(height); resize_term(opt_width, height); XSetInputFocus(dpy, termwin, RevertToPointerRoot, CurrentTime); XSync(dpy, False); } break; case ButtonPress: resize(); XSync(dpy, False); break; case UnmapNotify: if (event.xunmap.window == termwin) { if (opt_restart) { if (opt_restart_hidden) { roll(UP); hidden = 1; } init_xterm(0); XSync(dpy, False); if (opt_restart_hidden && last_focused) XSetInputFocus(dpy, last_focused, RevertToPointerRoot, CurrentTime); else XSetInputFocus(dpy, termwin, RevertToPointerRoot, CurrentTime); } else { if (last_focused) XSetInputFocus(dpy, last_focused, RevertToPointerRoot, CurrentTime); XSync(dpy, False); exit(0); } } break; } } return 0; }
bool Output::draw(cv::Point2f ui_offset) { boost::timer t1; bool window_decorations_on = getSignal("decor"); setSignal("decor", window_decorations_on); bm::setWindowDecorations(display, win, window_decorations_on); VLOG(3) << "decor draw time" << t1.elapsed(); /* XWindowAttributes xwAttr; Status ret = XGetWindowAttributes( display, win, &xwAttr ); int screen_w = xwAttr.width; int screen_h = xwAttr.height; if (ximage) XPutImage(display, win, gc, ximage, 0, 0, 0, 0, screen_w, screen_h); */ XWindowAttributes xwAttr, xwAttr2; // these don't seem to be updating x and y Window toplevel_parent = get_toplevel_parent(display, win); //Status ret = XGetWindowAttributes( display, win, &xwAttr ); // this has the real x and y position Status ret = XGetWindowAttributes( display, toplevel_parent, &xwAttr ); // this holds the 'true' width and height (the inner window not including // gnome decor?) the x and y are relative to the toplevel_parent Status ret2 = XGetWindowAttributes( display, win, &xwAttr2 ); VLOG(6) << name << " top " << xwAttr.x << " " << xwAttr.y << ", " << xwAttr.width << " " << xwAttr.height << " win " << xwAttr2.x << " " << xwAttr2.y << ", " << xwAttr2.width << " " << xwAttr2.height; // TBD the user ought to be able to force x,y,w,h changes // the logic would be that if the window attributes disagree with the last // update, use those, if the getSignal value is different than the old signal, // that means the user wants the window resized int wm_x = xwAttr.x; // + xwAttr2.x; int wm_y = xwAttr.y; // + xwAttr2.y; if ( (x != wm_x) || (y != wm_y) || (w != xwAttr2.width) || (h != xwAttr2.height) ) { // don't do anything, the window is already set properly x = wm_x; y = wm_y; w = xwAttr2.width; h = xwAttr2.height; VLOG(6) << name << " wm changed display " << x << " " << y << ", " << w << " " << h; setSignal("x", x); setSignal("y", y); setSignal("w", w); setSignal("h", h); } else { // see if user changed anything through vimjay interface, // this has lower priority than window manager changes int new_x = getSignal("x"); int new_y = getSignal("y"); int new_w = getSignal("w"); int new_h = getSignal("h"); if ( (x != new_x) || (y != new_y) || (w != new_w) || (h != new_h) ) { VLOG(6) << name << " vimjay changed display " << CLVAL << new_x << " " << new_y << ", " << new_w << " " << new_h << CLNRM << ", old " << CLVAL << x << " " << y << ", " << w << " " << h << CLNRM; //int dx = new_x - x; //int dy = new_y - y; x = new_x; y = new_y; w = new_w; h = new_h; XWindowChanges values; unsigned int value_mask = 0x0; values.x = x; values.y = y; // if the window is crammed against the right border, increasing width // results in shrinking the window which is strange values.width = w; values.height = h; VLOG(6) << values.x << " " << values.y; // TBD test if different { value_mask = CWWidth | CWHeight; value_mask |= CWX | CWY; XConfigureWindow( display, win, value_mask, &values); } // TBD if (win != toplevel_parent) { // TBD hack, the difference between the toplevel window and the // actual one are overcome by giving all of the offset to win zeroing // out the toplevel, when the wm changes the position it all goes to the toplevel. values.x = 0; values.y = 0; value_mask = CWX | CWY; XConfigureWindow( display, toplevel_parent, value_mask, &values); } setSignal("x", x); setSignal("y", y); setSignal("w", w); setSignal("h", h); } // see if vimjay ui change xywh } // xywh changes cv::Mat in = getImage("in"); //if (in.empty()) return true; if (!(in.empty()) && ximage) { // These aren't used, just provided for convenience // and are set here to make sure the user didn't try to override them // (TBD set to be unwriteable when that functionality is supported setSignal("im_w", Config::inst()->im_width); setSignal("im_h", Config::inst()->im_height); VLOG(4) << "attr time" << t1.elapsed(); // TBD is this necessary or does X do it for me if the window is resized? const cv::Size sz = cv::Size(w, h); cv::Mat scaled; if (sz == in.size()) scaled = in.clone(); else cv::resize(in, scaled, sz, 0, 0, getModeType() ); VLOG(5) << "resize time" << t1.elapsed(); XDestroyImage(ximage); ximage = XGetImage(display, DefaultRootWindow(display), 0, 0, w, h, AllPlanes, ZPixmap); VLOG(4) << "get im time" << t1.elapsed(); // this is slow bm::matToXImage(scaled, ximage, win, *display, *screen); VLOG(4) << "matToXImage time" << t1.elapsed(); XPutImage(display, win, gc, ximage, 0, 0, 0, 0, ximage->width, ximage->height); VLOG(3) << "put image time" << t1.elapsed(); } // ximage and input image is valid return ImageNode::draw(ui_offset); }