summaryrefslogtreecommitdiff
path: root/src/compositor/compositor-xrender.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/compositor/compositor-xrender.c')
-rw-r--r--src/compositor/compositor-xrender.c89
1 files changed, 89 insertions, 0 deletions
diff --git a/src/compositor/compositor-xrender.c b/src/compositor/compositor-xrender.c
index 37440a79..13e8e620 100644
--- a/src/compositor/compositor-xrender.c
+++ b/src/compositor/compositor-xrender.c
@@ -42,6 +42,8 @@
#include "display.h"
#include "../core/display-private.h"
+#include "../core/screen-private.h"
+#include "../core/workspace.h"
#include "screen.h"
#include "frame.h"
#include "errors.h"
@@ -49,6 +51,7 @@
#include "compositor-private.h"
#include "compositor-xrender.h"
#include "xprops.h"
+#include "core.h"
#include <X11/Xatom.h>
#include <X11/extensions/shape.h>
#include <X11/extensions/Xcomposite.h>
@@ -1856,6 +1859,87 @@ free_win (MetaCompWindow *cw,
}
static void
+constrain_tooltip_onscreen (MetaDisplay *display,
+ MetaScreen *screen,
+ MetaCompWindow *cw,
+ Window id)
+{
+ MetaWorkspace *workspace;
+ MetaRectangle work_area, win_rect;
+ const MetaXineramaScreenInfo* xinerama;
+ gint new_x, new_y;
+ gint active_workspace_num;
+
+ /* Why this is here:
+ * As of gtk 3.24, tooltips are positioned differently, and can end up off the
+ * screen in certain situations in hidpi.
+ *
+ * See: https://github.com/GNOME/gtk/commit/14d22cb3233e
+ *
+ * If the panel is too tall (around > 25 or so), tooltip positioning fails both
+ * tests in gdkwindowimpl.c (maybe_flip_position()) skipping repositioning of the
+ * tooltip inside the workarea. This only occurs on bottom panels.
+ *
+ * Since the calculations are based upon the monitor's workarea and the 'attach'
+ * (gdk) window's rectangle, there's no way to compensate for or fool gtk into
+ * displaying it correctly. So here, we do our own check and adjustment. */
+
+ active_workspace_num = meta_core_get_active_workspace (cw->attrs.screen);
+
+ workspace = meta_screen_get_workspace_by_index (screen,
+ active_workspace_num);
+
+ win_rect.x = cw->attrs.x;
+ win_rect.y = cw->attrs.y;
+ win_rect.width = cw->attrs.width;
+ win_rect.height = cw->attrs.height;
+
+ xinerama = meta_screen_get_xinerama_for_rect (screen,
+ &win_rect);
+
+ meta_workspace_get_work_area_for_xinerama (workspace,
+ xinerama->number,
+ &work_area);
+
+ new_x = win_rect.x;
+ new_y = win_rect.y;
+
+ /* Valid tooltip positions seem to cheat into the panel by a few pixels - maybe
+ * accounting for shadow margin. There's no reason the fix these, but they'd
+ * be caught here otherwise, so 10px of overshoot in the direction of the panel
+ * is allowed. The tooltips we're out to catch are the ones on the complete other
+ * side of the panel (off screren), so there won't be any confusion. */
+ if (win_rect.y < work_area.y - 10)
+ {
+ new_y = work_area.y;
+ }
+ else if (win_rect.y + win_rect.height > work_area.y + work_area.height + 10)
+ {
+ new_y = (work_area.y + work_area.height - win_rect.height);
+ }
+
+ if (win_rect.x < work_area.x - 10)
+ {
+ new_x = work_area.x;
+ }
+ else if (win_rect.x + win_rect.width > work_area.x + work_area.width + 10)
+ {
+ new_x = (work_area.x + work_area.width - win_rect.width);
+ }
+
+ if (new_x != win_rect.x || new_y != win_rect.y)
+ {
+ if (DISPLAY_COMPOSITOR (display)->debug)
+ {
+ fprintf(stderr, "Constraining tooltip onscreen x:%d -> %d, y:%d -> %d\n",
+ win_rect.x,new_x, win_rect.y,new_y);
+ }
+
+ XMoveWindow (display->xdisplay, cw->id, new_x, new_y);
+ }
+}
+
+static void
map_win (MetaDisplay *display,
MetaScreen *screen,
Window id)
@@ -1866,6 +1950,11 @@ map_win (MetaDisplay *display,
if (cw == NULL)
return;
+ if (cw->type == META_COMP_WINDOW_TOOLTIP)
+ {
+ constrain_tooltip_onscreen (display, screen, cw, id);
+ }
+
/* The reason we deallocate this here and not in unmap
is so that we will still have a valid pixmap for
whenever the window is unmapped */