Compare commits

...

8 Commits

Author SHA1 Message Date
32cc8fffb3 wip/resize
doesn't work...
2014-03-06 19:07:02 +01:00
abd2abcde6 cursor-tracker: Avoid unnecessary round trip 2014-03-06 17:31:08 +01:00
a8f4651c72 MetaCursorTracker: fix uninitialized screen variable
We must call gdk_device_get_pointer() unconditionally, because
that sets the GdkScreen argument we use to obtain the root window.
2014-03-06 17:27:11 +01:00
54df7934ea Bump version to 3.11.91
Update NEWS.
2014-03-05 23:48:33 +01:00
9052efb0d9 build: Use non-deprecated feature test macros
_SVID_SOURCE has been deprecated in newer versions of glibc breaking
-WError; the recommended replacement of _DEFAULT_SOURCE is fairly
new, so switch to _XOPEN_SOURCE instead.
2014-03-05 23:48:33 +01:00
b346f98eb0 Fix positioning error for manually positioned windows
The "original coordinates" passed into meta_window_place() were the
coordinates of the client rectangle not the frame rectangle. When
meta_window_place() didn't place because the window was manually
positioned (e.g., 'xterm -geometry +x+y') that resulted in a window
being offset by the frame dimensions.

https://bugzilla.gnome.org/show_bug.cgi?id=724049
2014-03-05 17:22:56 -05:00
365af53797 Fix handling of dynamic updates to colors/font/etc.
Since the introduction of frame sync in GTK+, updates to titlebar font and
colors haven't been working because GTK+ counts on the frame clock to
do style updates, and the frame clock doesn't run for an unmapped
GdkWindow. (It's possible that GtkStyleContext changes subsequent to
the introduction of the frame clock were also needed to fully break
things.)

We actually need to map the MetaFrames GdkWindow and let the
compositor code send out the frame sync messages in order to pick up
style changes.

Hopefully no bad side effects will occur from this - we make the window
override-redirect, 1x1, and outside the bounds of the screen.

https://bugzilla.gnome.org/show_bug.cgi?id=725751
2014-03-05 17:22:48 -05:00
bee59ec0e1 Use MetaCursorTracker to query the pointer position
Functionally equivalent in the X11 case, but also correct for
Wayland (where the X server doesn't have the updated pointer
position).

https://bugzilla.gnome.org/show_bug.cgi?id=725525
2014-03-05 23:09:48 +01:00
12 changed files with 126 additions and 222 deletions

14
NEWS
View File

@ -1,3 +1,17 @@
3.11.91
=======
* Don't use keysym to match keybindings [Rui; #678001]
* Fix message tray icons showing up blank (again) [Adel; #725180]
* Improve keybinding lookups [Rui; #725588]
* Fix dynamic updates of titlebar style properties [Owen; #725751]
* Fix positioning of manually positioned windows [Owen; #724049]
* Misc bug fixes and cleanups [Jasper, Carlos, Adel, Giovanni, Florian; #720631,
#724969, #725216, #724402, #722266, #725338, #725525]
Contributors:
Giovanni Campagna, Adel Gadllah, Carlos Garnacho, Rui Matos, Florian Müllner,
Jasper St. Pierre, Owen W. Taylor
3.11.90
=======
* Fix double-scaling on high DPI resolutions [Adel; #723931]

View File

@ -3,7 +3,7 @@ AC_CONFIG_MACRO_DIR([m4])
m4_define([mutter_major_version], [3])
m4_define([mutter_minor_version], [11])
m4_define([mutter_micro_version], [90])
m4_define([mutter_micro_version], [91])
m4_define([mutter_version],
[mutter_major_version.mutter_minor_version.mutter_micro_version])

View File

@ -491,12 +491,17 @@ place_window_if_needed(MetaWindow *window,
!window->minimized &&
!window->fullscreen)
{
MetaRectangle orig_rect;
MetaRectangle placed_rect;
MetaWorkspace *cur_workspace;
const MetaMonitorInfo *monitor_info;
meta_window_get_frame_rect (window, &placed_rect);
meta_window_place (window, info->orig.x, info->orig.y,
orig_rect = info->orig;
extend_by_frame (window, &orig_rect);
meta_window_place (window, orig_rect.x, orig_rect.y,
&placed_rect.x, &placed_rect.y);
did_placement = TRUE;

View File

@ -42,7 +42,7 @@
*/
#define _GNU_SOURCE
#define _SVID_SOURCE /* for putenv() and some signal-related functions */
#define _XOPEN_SOURCE /* for putenv() and some signal-related functions */
#include <config.h>
#include <meta/main.h>

View File

@ -1074,12 +1074,13 @@ get_pointer_position_gdk (int *x,
GdkScreen *gscreen;
gmanager = gdk_display_get_device_manager (gdk_display_get_default ());
gdevice = gdk_device_manager_get_client_pointer (gmanager);
gdevice = gdk_x11_device_manager_lookup (gmanager, META_VIRTUAL_CORE_POINTER_ID);
gdk_device_get_position (gdevice, &gscreen, x, y);
gdk_device_get_state (gdevice,
gdk_screen_get_root_window (gscreen),
NULL, (GdkModifierType*)mods);
if (mods)
gdk_device_get_state (gdevice,
gdk_screen_get_root_window (gscreen),
NULL, (GdkModifierType*)mods);
}
static void
@ -1095,9 +1096,12 @@ get_pointer_position_clutter (int *x,
cdevice = clutter_device_manager_get_core_device (cmanager, CLUTTER_POINTER_DEVICE);
clutter_input_device_get_coords (cdevice, NULL, &point);
*x = point.x;
*y = point.y;
*mods = clutter_input_device_get_modifier_state (cdevice);
if (x)
*x = point.x;
if (y)
*y = point.y;
if (mods)
*mods = clutter_input_device_get_modifier_state (cdevice);
}
void

View File

@ -1514,38 +1514,19 @@ meta_screen_get_mouse_window (MetaScreen *screen,
MetaWindow *not_this_one)
{
MetaWindow *window;
Window root_return, child_return;
double root_x_return, root_y_return;
double win_x_return, win_y_return;
XIButtonState buttons;
XIModifierState mods;
XIGroupState group;
int x, y;
if (not_this_one)
meta_topic (META_DEBUG_FOCUS,
"Focusing mouse window excluding %s\n", not_this_one->desc);
meta_error_trap_push (screen->display);
XIQueryPointer (screen->display->xdisplay,
META_VIRTUAL_CORE_POINTER_ID,
screen->xroot,
&root_return,
&child_return,
&root_x_return,
&root_y_return,
&win_x_return,
&win_y_return,
&buttons,
&mods,
&group);
meta_error_trap_pop (screen->display);
free (buttons.mask);
meta_cursor_tracker_get_pointer (screen->cursor_tracker,
&x, &y, NULL);
window = meta_stack_get_default_focus_window_at_point (screen->stack,
screen->active_workspace,
not_this_one,
root_x_return,
root_y_return);
x, y);
return window;
}
@ -1827,28 +1808,11 @@ meta_screen_get_current_monitor (MetaScreen *screen)
if (screen->display->monitor_cache_invalidated)
{
Window root_return, child_return;
double win_x_return, win_y_return;
double root_x_return, root_y_return;
XIButtonState buttons;
XIModifierState mods;
XIGroupState group;
int x, y;
XIQueryPointer (screen->display->xdisplay,
META_VIRTUAL_CORE_POINTER_ID,
screen->xroot,
&root_return,
&child_return,
&root_x_return,
&root_y_return,
&win_x_return,
&win_y_return,
&buttons,
&mods,
&group);
free (buttons.mask);
meta_screen_get_current_monitor_for_pos (screen, root_x_return, root_y_return);
meta_cursor_tracker_get_pointer (screen->cursor_tracker,
&x, &y, NULL);
meta_screen_get_current_monitor_for_pos (screen, x, y);
}
return screen->last_monitor_index;

View File

@ -408,12 +408,6 @@ struct _MetaWindow
*/
MetaRectangle rect;
/* The size and position we want the window to be (i.e. what we last asked
* the client to configure).
* This is only used for wayland clients.
*/
MetaRectangle expected_rect;
gboolean has_custom_frame_extents;
GtkBorder custom_frame_extents;

View File

@ -35,7 +35,7 @@
*/
#define _GNU_SOURCE
#define _SVID_SOURCE /* for gethostname() */
#define _XOPEN_SOURCE 500 /* for gethostname() */
#include <config.h>
#include "window-props.h"

View File

@ -38,6 +38,7 @@
#include <meta/common.h>
#include <meta/errors.h>
#include <meta/prefs.h>
#include <meta/meta-cursor-tracker.h>
#include "window-private.h"
#include "window-props.h"
@ -673,35 +674,19 @@ meta_window_x11_property_notify (MetaWindow *window,
static int
query_pressed_buttons (MetaWindow *window)
{
double x, y, query_root_x, query_root_y;
Window root, child;
XIButtonState buttons;
XIModifierState mods;
XIGroupState group;
ClutterModifierType mods;
int button = 0;
meta_error_trap_push (window->display);
XIQueryPointer (window->display->xdisplay,
META_VIRTUAL_CORE_POINTER_ID,
window->xwindow,
&root, &child,
&query_root_x, &query_root_y,
&x, &y,
&buttons, &mods, &group);
meta_cursor_tracker_get_pointer (window->screen->cursor_tracker,
NULL, NULL, &mods);
if (meta_error_trap_pop_with_return (window->display) != Success)
goto out;
if (XIMaskIsSet (buttons.mask, Button1))
if (mods & CLUTTER_BUTTON1_MASK)
button |= 1 << 1;
if (XIMaskIsSet (buttons.mask, Button2))
if (mods & CLUTTER_BUTTON2_MASK)
button |= 1 << 2;
if (XIMaskIsSet (buttons.mask, Button3))
if (mods & CLUTTER_BUTTON3_MASK)
button |= 1 << 3;
free (buttons.mask);
out:
return button;
}

View File

@ -86,8 +86,9 @@ static void meta_window_show (MetaWindow *window);
static void meta_window_hide (MetaWindow *window);
static void meta_window_save_rect (MetaWindow *window);
static void save_user_window_placement (MetaWindow *window);
static void force_save_user_window_placement (MetaWindow *window);
static void save_user_window_placement (MetaWindow *window,
MetaRectangle *rect,
gboolean force);
static void meta_window_move_resize_internal (MetaWindow *window,
MetaMoveResizeFlags flags,
@ -3041,42 +3042,39 @@ meta_window_save_rect (MetaWindow *window)
}
}
/**
* force_save_user_window_placement:
* @window: Store current position of this window for future reference
*
* Save the user_rect regardless of whether the window is maximized or
* fullscreen. See save_user_window_placement() for most uses.
*/
static void
force_save_user_window_placement (MetaWindow *window)
{
meta_window_get_client_root_coords (window, &window->user_rect);
}
/**
/*
* save_user_window_placement:
* @window: Store current position of this window for future reference
*
* Save the user_rect, but only if the window is neither maximized nor
* fullscreen, otherwise the window may snap back to those dimensions
* (bug #461927).
* @rect: the rectangle with the position we want (in case it's not yet
* assumed by the window, which happens for wayland resizes), or
* %NULL to use the current window position
* @force: save the user_rect regardless of whether the window is maximized or
* fullscreen
*/
static void
save_user_window_placement (MetaWindow *window)
save_user_window_placement (MetaWindow *window,
MetaRectangle *rect,
gboolean force)
{
if (!(META_WINDOW_MAXIMIZED (window) || META_WINDOW_TILED_SIDE_BY_SIDE (window) || window->fullscreen))
gboolean should_save = !META_WINDOW_MAXIMIZED (window) &&
!META_WINDOW_TILED_SIDE_BY_SIDE (window) &&
!window->fullscreen;
if (force || should_save)
{
MetaRectangle user_rect;
meta_window_get_client_root_coords (window, &user_rect);
if (rect)
user_rect = *rect;
else
meta_window_get_client_root_coords (window, &user_rect);
if (!window->maximized_horizontally)
if (force || !window->maximized_horizontally)
{
window->user_rect.x = user_rect.x;
window->user_rect.width = user_rect.width;
}
if (!window->maximized_vertically)
if (force || !window->maximized_vertically)
{
window->user_rect.y = user_rect.y;
window->user_rect.height = user_rect.height;
@ -3586,7 +3584,7 @@ meta_window_unmaximize_internal (MetaWindow *window,
/* Make sure user_rect is current.
*/
force_save_user_window_placement (window);
save_user_window_placement (window, NULL, TRUE);
/* When we unmaximize, if we're doing a mouse move also we could
* get the window suddenly jumping to the upper left corner of
@ -3763,7 +3761,7 @@ meta_window_unmake_fullscreen (MetaWindow *window)
/* Make sure user_rect is current.
*/
force_save_user_window_placement (window);
save_user_window_placement (window, NULL, TRUE);
meta_window_update_layer (window);
@ -4593,73 +4591,29 @@ meta_window_move_resize_internal (MetaWindow *window,
* it can be for maximized or fullscreen.
*
*/
root_x_nw = new_rect.x;
root_y_nw = new_rect.y;
/* First, save where we would like the client to be. This is used by the next
* attach to determine if the client is really moving/resizing or not.
*/
window->expected_rect = new_rect;
if (is_wayland_resize)
{
/* This is a call to wl_surface_commit(), ignore the new_rect and
* update the real client size to match the buffer size.
*/
window->rect.width = w;
window->rect.height = h;
}
if (new_rect.width != window->rect.width ||
new_rect.height != window->rect.height)
{
/* We need to resize the client. Resizing is in two parts:
* some of the movement happens immediately, and some happens as part
* of the resizing (through dx/dy in wl_surface_attach).
*
* To do so, we need to compute the resize from the point of the view
* of the client, and then adjust the immediate resize to match.
*
* dx/dy are the values we expect from the new attach(), while deltax/
* deltay reflect the overall movement.
*/
MetaRectangle client_rect;
int dx, dy;
int deltax, deltay;
meta_rectangle_resize_with_gravity (&old_rect,
&client_rect,
gravity,
new_rect.width,
new_rect.height);
deltax = new_rect.x - old_rect.x;
deltay = new_rect.y - old_rect.y;
dx = client_rect.x - old_rect.x;
dy = client_rect.y - old_rect.y;
if (deltax != dx || deltay != dy)
need_move_client = TRUE;
window->rect.x += (deltax - dx);
window->rect.y += (deltay - dy);
if (!is_wayland_resize)
/* Politely ask for a new size, and wait until the next commit. */
meta_wayland_surface_configure_notify (window->surface,
new_rect.width,
new_rect.height);
/* We need to update window->rect here, otherwise all sorts of
bad stuff happens with interactive resizes... */
need_resize_client = TRUE;
meta_wayland_surface_configure_notify (window->surface,
new_rect.width,
new_rect.height);
}
else
{
/* No resize happening, we can just move the window and live with it. */
if (window->rect.x != new_rect.x ||
window->rect.y != new_rect.y)
need_move_client = TRUE;
window->rect.x = new_rect.x;
window->rect.y = new_rect.y;
}
if (window->rect.x != new_rect.x ||
window->rect.y != new_rect.y)
need_move_client = TRUE;
window->rect.x = new_rect.x;
window->rect.y = new_rect.y;
window->rect.width = new_rect.width;
window->rect.height = new_rect.height;
}
else
{
@ -4971,9 +4925,9 @@ meta_window_move_resize_internal (MetaWindow *window,
}
if (!window->placed && window->force_save_user_rect && !window->fullscreen)
force_save_user_window_placement (window);
save_user_window_placement (window, &new_rect, TRUE);
else if (is_user_action)
save_user_window_placement (window);
save_user_window_placement (window, &new_rect, FALSE);
if (need_move_client || need_move_frame)
g_signal_emit (window, window_signals[POSITION_CHANGED], 0);
@ -5074,10 +5028,10 @@ meta_window_move_resize_wayland (MetaWindow *window,
meta_window_get_position (window, &x, &y);
x += dx; y += dy;
if (x != window->expected_rect.x || y != window->expected_rect.y)
if (x != window->rect.x || y != window->rect.y)
flags |= META_IS_MOVE_ACTION;
if (width != window->expected_rect.width ||
height != window->expected_rect.height)
if (width != window->rect.width ||
height != window->rect.height)
flags |= META_IS_RESIZE_ACTION;
meta_window_move_resize_internal (window, flags, NorthWestGravity,
@ -6344,7 +6298,7 @@ meta_window_move_resize_request (MetaWindow *window,
*
* See also bug 426519.
*/
save_user_window_placement (window);
save_user_window_placement (window, NULL, FALSE);
}
/*
@ -10343,25 +10297,15 @@ window_focus_on_pointer_rest_callback (gpointer data)
MetaWindow *window = focus_data->window;
MetaDisplay *display = window->display;
MetaScreen *screen = window->screen;
Window root, child;
double root_x, root_y, x, y;
int root_x, root_y;
guint32 timestamp;
XIButtonState buttons;
XIModifierState mods;
XIGroupState group;
ClutterActor *child;
if (meta_prefs_get_focus_mode () == G_DESKTOP_FOCUS_MODE_CLICK)
goto out;
meta_error_trap_push (display);
XIQueryPointer (display->xdisplay,
META_VIRTUAL_CORE_POINTER_ID,
screen->xroot,
&root, &child,
&root_x, &root_y, &x, &y,
&buttons, &mods, &group);
meta_error_trap_pop (display);
free (buttons.mask);
meta_cursor_tracker_get_pointer (screen->cursor_tracker,
&root_x, &root_y, NULL);
if (root_x != focus_data->pointer_x ||
root_y != focus_data->pointer_y)
@ -10371,17 +10315,15 @@ window_focus_on_pointer_rest_callback (gpointer data)
return TRUE;
}
/* Explicitly check for the overlay window, as get_focus_window_at_point()
* may return windows that extend underneath the chrome (like
* override-redirect or DESKTOP windows)
*/
if (child == meta_get_overlay_window (screen))
child = clutter_stage_get_actor_at_pos (CLUTTER_STAGE (clutter_stage_get_default ()),
CLUTTER_PICK_REACTIVE, root_x, root_y);
if (!META_IS_SURFACE_ACTOR (child))
goto out;
window =
meta_stack_get_default_focus_window_at_point (screen->stack,
screen->active_workspace,
None, root_x, root_y);
NULL, root_x, root_y);
if (window == NULL)
goto out;

View File

@ -44,8 +44,6 @@
static void meta_frames_destroy (GtkWidget *object);
static void meta_frames_finalize (GObject *object);
static void meta_frames_style_updated (GtkWidget *widget);
static void meta_frames_map (GtkWidget *widget);
static void meta_frames_unmap (GtkWidget *widget);
static void meta_frames_update_prelit_control (MetaFrames *frames,
MetaUIFrame *frame,
@ -134,9 +132,6 @@ meta_frames_class_init (MetaFramesClass *class)
widget_class->style_updated = meta_frames_style_updated;
widget_class->map = meta_frames_map;
widget_class->unmap = meta_frames_unmap;
widget_class->draw = meta_frames_draw;
widget_class->destroy_event = meta_frames_destroy_event;
widget_class->button_press_event = meta_frames_button_press_event;
@ -231,6 +226,7 @@ meta_frames_init (MetaFrames *frames)
frames->style_variants = g_hash_table_new_full (g_str_hash, g_str_equal,
g_free, g_object_unref);
update_style_contexts (frames);
gtk_widget_set_double_buffered (GTK_WIDGET (frames), FALSE);
@ -522,13 +518,26 @@ MetaFrames*
meta_frames_new (int screen_number)
{
GdkScreen *screen;
MetaFrames *frames;
screen = gdk_display_get_screen (gdk_display_get_default (),
screen_number);
return g_object_new (META_TYPE_FRAMES,
"screen", screen,
NULL);
frames = g_object_new (META_TYPE_FRAMES,
"screen", screen,
"type", GTK_WINDOW_POPUP,
NULL);
/* Put the window at an arbitrary offscreen location; the one place
* it can't be is at -100x-100, since the meta_window_new() will
* mistake it for a window created via meta_create_offscreen_window()
* and ignore it, and we need this window to get frame-synchronization
* messages so that GTK+'s style change handling works.
*/
gtk_window_move (GTK_WINDOW (frames), -200, -200);
gtk_window_resize (GTK_WINDOW (frames), 1, 1);
return frames;
}
/* In order to use a style with a window it has to be attached to that
@ -635,22 +644,6 @@ meta_frames_unmanage_window (MetaFrames *frames,
meta_warning ("Frame 0x%lx not managed, can't unmanage\n", xwindow);
}
static void
meta_frames_map (GtkWidget *widget)
{
/* We override the parent map function to a no-op because we don't
* want to actually show the GDK window. But GTK needs to think that
* the widget is mapped or it won't deliver the events we care about.
*/
gtk_widget_set_mapped (widget, TRUE);
}
static void
meta_frames_unmap (GtkWidget *widget)
{
gtk_widget_set_mapped (widget, FALSE);
}
static MetaUIFrame*
meta_frames_lookup_window (MetaFrames *frames,
Window xwindow)

View File

@ -295,9 +295,12 @@ meta_ui_new (Display *xdisplay,
g_assert (gdisplay == gdk_display_get_default ());
ui->frames = meta_frames_new (XScreenNumberOfScreen (screen));
/* This does not actually show any widget. MetaFrames has been hacked so
* that showing it doesn't actually do anything. But we need the flags
* set for GTK to deliver events properly. */
/* GTK+ needs the frame-sync protocol to work in order to properly
* handle style changes. This means that the dummy widget we create
* to get the style for title bars actually needs to be mapped
* and fully tracked as a MetaWindow. Horrible, but mostly harmless -
* the window is a 1x1 overide redirect window positioned offscreen.
*/
gtk_widget_show (GTK_WIDGET (ui->frames));
g_object_set_data (G_OBJECT (gdisplay), "meta-ui", ui);