summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarsten Haitzler (Rasterman) <raster@rasterman.com>2020-01-07 14:20:58 +0000
committerCarsten Haitzler (Rasterman) <raster@rasterman.com>2020-01-07 14:24:13 +0000
commit33402436236c48677ab84fb94d05d7c6e3d2f946 (patch)
treee746fc395ae16e89da273bf750b09b747616cade
parentd3dc7dc86e854c41d166bc02340f53d3ab4f2a0f (diff)
ecore-x add root barrier setup func to fix xserver mouse containment
xserver stopped containing mouse to screen bounds a while back... this si broken. so enforce this policy with an api that take a list of screen rects (relative to root) and makes those the barrier bounds so that mouse doesn't go out of the screen anymore. new api to enable this fix in e.
-rw-r--r--src/lib/ecore_x/Ecore_X.h1
-rw-r--r--src/lib/ecore_x/ecore_x_fixes.c99
2 files changed, 100 insertions, 0 deletions
diff --git a/src/lib/ecore_x/Ecore_X.h b/src/lib/ecore_x/Ecore_X.h
index b58520c1b3..bb5aedf39e 100644
--- a/src/lib/ecore_x/Ecore_X.h
+++ b/src/lib/ecore_x/Ecore_X.h
@@ -2432,6 +2432,7 @@ EAPI void ecore_x_region_window_shape_set(Ecore_X_Region region, E
2432EAPI void ecore_x_region_picture_clip_set(Ecore_X_Region region, Ecore_X_Picture picture, int x_origin, int y_origin); 2432EAPI void ecore_x_region_picture_clip_set(Ecore_X_Region region, Ecore_X_Picture picture, int x_origin, int y_origin);
2433EAPI void ecore_x_cursor_show(void); 2433EAPI void ecore_x_cursor_show(void);
2434EAPI void ecore_x_cursor_hide(void); 2434EAPI void ecore_x_cursor_hide(void);
2435EAPI void ecore_x_root_screen_barriers_set(Ecore_X_Rectangle *screens, int num); /** @since 1.24 */
2435 2436
2436/** 2437/**
2437 * xfixes selection notification request. 2438 * xfixes selection notification request.
diff --git a/src/lib/ecore_x/ecore_x_fixes.c b/src/lib/ecore_x/ecore_x_fixes.c
index dd81b674c8..5582c3e3ef 100644
--- a/src/lib/ecore_x/ecore_x_fixes.c
+++ b/src/lib/ecore_x/ecore_x_fixes.c
@@ -7,6 +7,8 @@
7#include "ecore_x_private.h" 7#include "ecore_x_private.h"
8#include "Ecore_X.h" 8#include "Ecore_X.h"
9 9
10#include <X11/Xregion.h>
11
10static int _fixes_available; 12static int _fixes_available;
11#ifdef ECORE_XFIXES 13#ifdef ECORE_XFIXES
12static int _fixes_major, _fixes_minor; 14static int _fixes_major, _fixes_minor;
@@ -434,3 +436,100 @@ ecore_x_cursor_hide(void)
434 } 436 }
435#endif /* ifdef ECORE_XFIXES */ 437#endif /* ifdef ECORE_XFIXES */
436} 438}
439
440EAPI void
441ecore_x_root_screen_barriers_set(Ecore_X_Rectangle *screens, int num)
442{
443#ifdef ECORE_XFIXES
444 static PointerBarrier *bar = NULL;
445 static int bar_num = 0;
446 static int bar_alloc = 0;
447 Region reg, reg2, reg3;
448 int i, j;
449
450 // clear out old root screen barriers....
451 if (bar)
452 {
453 for (i = 0; i < bar_num; i++)
454 {
455 XFixesDestroyPointerBarrier(_ecore_x_disp, bar[i]);
456 }
457 free(bar);
458 }
459 bar = NULL;
460 bar_num = 0;
461 bar_alloc = 0;
462 if ((!screens) || (num <= 0)) return;
463
464 // set up new ones given the screen list given
465 for (i = 0; i < num; i++)
466 {
467 XRectangle xrect;
468
469 reg = XCreateRegion();
470 reg2 = XCreateRegion();
471 xrect.x = screens[i].x - 1;
472 xrect.y = screens[i].y - 1;
473 xrect.width = screens[i].width + 2;
474 xrect.height = screens[i].height + 2;
475 XUnionRectWithRegion(&xrect, reg, reg2);
476 XDestroyRegion(reg);
477 reg = reg2;
478
479 // reg == screen i + 1 pixel surrounding it
480 for (j = 0; j < num; j++)
481 {
482 // create a region representing screen j
483 reg2 = XCreateRegion();
484 reg3 = XCreateRegion();
485 xrect.x = screens[j].x;
486 xrect.y = screens[j].y;
487 xrect.width = screens[j].width;
488 xrect.height = screens[j].height;
489 XUnionRectWithRegion(&xrect, reg2, reg3);
490 XDestroyRegion(reg2);
491 reg2 = reg3;
492 // reg2 == screen j
493
494 reg3 = XCreateRegion();
495 XSubtractRegion(reg, reg2, reg3);
496 XDestroyRegion(reg);
497 XDestroyRegion(reg2);
498 reg = reg3;
499 // reg now has had screen j cut out of the boundary
500 }
501 // reg is the result of starting with screen i and then with a
502 // 1 pixel boundary around it havnig adjacent screens "cut out"
503 // of that boundary leaving only extra bounds where no screens
504 // are adjacent
505
506 // walk rects and create barriers
507 for (j = 0; j < reg->numRects; j++)
508 {
509 int x1, y1, x2, y2;
510
511 bar_num++;
512 if (bar_num > bar_alloc)
513 {
514 bar_alloc += 32;
515 PointerBarrier *t = realloc(bar, bar_alloc * sizeof(PointerBarrier));
516 if (!t)
517 {
518 bar_num--;
519 return;
520 }
521 bar = t;
522 }
523 x1 = reg->rects[j].x1;
524 y1 = reg->rects[j].y1;
525 x2 = reg->rects[j].x2 - 1;
526 y2 = reg->rects[j].y2 - 1;
527 bar[bar_num - 1] =
528 XFixesCreatePointerBarrier(_ecore_x_disp,
529 DefaultRootWindow(_ecore_x_disp),
530 x1, y1, x2, y2, 0, 0, NULL);
531 }
532 XDestroyRegion(reg);
533 }
534#endif
535}