summaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
Diffstat (limited to 'src/core')
-rw-r--r--src/core/display-private.h5
-rw-r--r--src/core/display.c40
-rw-r--r--src/core/edge-resistance.c18
-rw-r--r--src/core/keybindings.c40
-rw-r--r--src/core/place.c52
-rw-r--r--src/core/prefs.c77
-rw-r--r--src/core/window-private.h3
-rw-r--r--src/core/window.c44
-rw-r--r--src/core/workspace.c9
-rw-r--r--src/core/xprops.c40
10 files changed, 224 insertions, 104 deletions
diff --git a/src/core/display-private.h b/src/core/display-private.h
index dc270a96..069e0ccf 100644
--- a/src/core/display-private.h
+++ b/src/core/display-private.h
@@ -276,8 +276,6 @@ struct _MetaDisplay {
#ifdef HAVE_COMPOSITE_EXTENSIONS
int composite_event_base;
int composite_error_base;
- int composite_major_version;
- int composite_minor_version;
int damage_event_base;
int damage_error_base;
int xfixes_event_base;
@@ -420,8 +418,7 @@ void meta_display_ungrab_focus_window_button (MetaDisplay *display,
MetaWindow *window);
/* Next two functions are defined in edge-resistance.c */
-void meta_display_compute_resistance_and_snapping_edges (MetaDisplay *display);
-void meta_display_cleanup_edges (MetaDisplay *display);
+void meta_display_cleanup_edges (MetaDisplay *display);
/* make a request to ensure the event serial has changed */
void meta_display_increment_event_serial (MetaDisplay *display);
diff --git a/src/core/display.c b/src/core/display.c
index 6a4831fb..caa76247 100644
--- a/src/core/display.c
+++ b/src/core/display.c
@@ -558,6 +558,9 @@ meta_display_open (void)
#ifdef HAVE_COMPOSITE_EXTENSIONS
{
+ int composite_major_version = 0;
+ int composite_minor_version = 0;
+
the_display->have_composite = FALSE;
the_display->composite_error_base = 0;
@@ -572,18 +575,16 @@ meta_display_open (void)
}
else
{
- the_display->composite_major_version = 0;
- the_display->composite_minor_version = 0;
if (XCompositeQueryVersion (the_display->xdisplay,
- &the_display->composite_major_version,
- &the_display->composite_minor_version))
+ &composite_major_version,
+ &composite_minor_version))
{
the_display->have_composite = TRUE;
}
else
{
- the_display->composite_major_version = 0;
- the_display->composite_minor_version = 0;
+ composite_major_version = 0;
+ composite_minor_version = 0;
}
}
@@ -591,8 +592,8 @@ meta_display_open (void)
"extn ver %d %d\n",
the_display->composite_error_base,
the_display->composite_event_base,
- the_display->composite_major_version,
- the_display->composite_minor_version);
+ composite_major_version,
+ composite_minor_version);
the_display->have_damage = FALSE;
@@ -3662,18 +3663,6 @@ meta_display_begin_grab_op (MetaDisplay *display,
g_assert (display->grab_window != NULL || display->grab_screen != NULL);
g_assert (display->grab_op != META_GRAB_OP_NONE);
- /* If this is a move or resize, cache the window edges for
- * resistance/snapping
- */
- if (meta_grab_op_is_resizing (display->grab_op) ||
- meta_grab_op_is_moving (display->grab_op))
- {
- meta_topic (META_DEBUG_WINDOW_OPS,
- "Computing edges to resist-movement or snap-to for %s.\n",
- window->desc);
- meta_display_compute_resistance_and_snapping_edges (display);
- }
-
/* Save the old stacking */
if (GRAB_OP_IS_WINDOW_SWITCH (display->grab_op))
{
@@ -5401,17 +5390,6 @@ meta_display_remove_autoraise_callback (MetaDisplay *display)
}
}
-#ifdef HAVE_COMPOSITE_EXTENSIONS
-void
-meta_display_get_compositor_version (MetaDisplay *display,
- int *major,
- int *minor)
-{
- *major = display->composite_major_version;
- *minor = display->composite_minor_version;
-}
-#endif
-
Display *
meta_display_get_xdisplay (MetaDisplay *display)
{
diff --git a/src/core/edge-resistance.c b/src/core/edge-resistance.c
index 51e77d54..aa4fcb6a 100644
--- a/src/core/edge-resistance.c
+++ b/src/core/edge-resistance.c
@@ -63,6 +63,8 @@ struct MetaEdgeResistanceData
ResistanceDataForAnEdge bottom_data;
};
+static void compute_resistance_and_snapping_edges (MetaDisplay *display);
+
/* !WARNING!: this function can return invalid indices (namely, either -1 or
* edges->len); this is by design, but you need to remember this.
*/
@@ -550,7 +552,9 @@ apply_edge_resistance_to_each_side (MetaDisplay *display,
gboolean modified;
int new_left, new_right, new_top, new_bottom;
- g_assert (display->grab_edge_resistance_data != NULL);
+ if (display->grab_edge_resistance_data == NULL)
+ compute_resistance_and_snapping_edges (display);
+
edge_data = display->grab_edge_resistance_data;
if (auto_snap)
@@ -671,7 +675,8 @@ meta_display_cleanup_edges (MetaDisplay *display)
MetaEdgeResistanceData *edge_data = display->grab_edge_resistance_data;
GHashTable *edges_to_be_freed;
- g_assert (edge_data != NULL);
+ if (edge_data == NULL) /* Not currently cached */
+ return;
/* We first need to clean out any window edges */
edges_to_be_freed = g_hash_table_new_full (g_direct_hash, g_direct_equal,
@@ -938,8 +943,8 @@ initialize_grab_edge_resistance_data (MetaDisplay *display)
edge_data->bottom_data.keyboard_buildup = 0;
}
-void
-meta_display_compute_resistance_and_snapping_edges (MetaDisplay *display)
+static void
+compute_resistance_and_snapping_edges (MetaDisplay *display)
{
GList *stacked_windows;
GList *cur_window_iter;
@@ -952,6 +957,11 @@ meta_display_compute_resistance_and_snapping_edges (MetaDisplay *display)
*/
GSList *rem_windows, *rem_win_stacking;
+ g_assert (display->grab_window != NULL);
+ meta_topic (META_DEBUG_WINDOW_OPS,
+ "Computing edges to resist-movement or snap-to for %s.\n",
+ display->grab_window->desc);
+
/*
* 1st: Get the list of relevant windows, from bottom to top
*/
diff --git a/src/core/keybindings.c b/src/core/keybindings.c
index 821d432a..068199b8 100644
--- a/src/core/keybindings.c
+++ b/src/core/keybindings.c
@@ -2329,7 +2329,7 @@ static void
error_on_command (int command_index,
const char *command,
const char *message,
- int screen_number,
+ const char *screen_name,
guint32 timestamp)
{
if (command_index < 0)
@@ -2358,7 +2358,7 @@ error_on_command (int command_index,
meta_show_dialog ("--error",
text,
NULL,
- screen_number,
+ screen_name,
NULL, NULL, 0,
NULL, NULL);
@@ -2370,7 +2370,7 @@ error_on_command (int command_index,
meta_show_dialog ("--error",
message,
NULL,
- screen_number,
+ screen_name,
NULL, NULL, 0,
NULL, NULL);
}
@@ -2441,7 +2441,7 @@ handle_run_command (MetaDisplay *display,
s = g_strdup_printf (_("No command %d has been defined.\n"),
which + 1);
- error_on_command (which, NULL, s, screen->number, event->xkey.time);
+ error_on_command (which, NULL, s, screen->screen_name, event->xkey.time);
g_free (s);
return;
@@ -2450,7 +2450,7 @@ handle_run_command (MetaDisplay *display,
err = NULL;
if (!meta_spawn_command_line_async_on_screen (command, screen, &err))
{
- error_on_command (which, command, err->message, screen->number, event->xkey.time);
+ error_on_command (which, command, err->message, screen->screen_name, event->xkey.time);
g_error_free (err);
}
@@ -3058,7 +3058,6 @@ handle_toggle_above (MetaDisplay *display,
meta_window_make_above (window);
}
-/* TODO: actually use this keybinding, without messing up the existing keybinding schema */
static void
handle_toggle_tiled (MetaDisplay *display,
MetaScreen *screen,
@@ -3071,14 +3070,20 @@ handle_toggle_tiled (MetaDisplay *display,
if ((META_WINDOW_TILED_LEFT (window) && mode == META_TILE_LEFT) ||
(META_WINDOW_TILED_RIGHT (window) && mode == META_TILE_RIGHT))
{
- window->tile_mode = META_TILE_NONE;
-
if (window->saved_maximize)
- meta_window_maximize (window, META_MAXIMIZE_VERTICAL |
- META_MAXIMIZE_HORIZONTAL);
- else
- meta_window_unmaximize (window, META_MAXIMIZE_VERTICAL |
+ {
+ window->tile_mode = META_TILE_MAXIMIZED;
+ window->tile_monitor_number = meta_screen_get_xinerama_for_window (window->screen, window)->number;
+ meta_window_maximize (window, META_MAXIMIZE_VERTICAL |
META_MAXIMIZE_HORIZONTAL);
+ }
+ else
+ {
+ window->tile_mode = META_TILE_NONE;
+ window->tile_monitor_number = -1;
+ meta_window_unmaximize (window, META_MAXIMIZE_VERTICAL |
+ META_MAXIMIZE_HORIZONTAL);
+ }
}
else if (meta_window_can_tile (window))
{
@@ -3090,6 +3095,13 @@ handle_toggle_tiled (MetaDisplay *display,
* we just set the flag and rely on meta_window_tile() syncing it to
* save an additional roundtrip.
*/
+
+ /* If we skip meta_window_unmaximize we have to manually reset the
+ * window->saved_maximize flag.
+ */
+ if (!META_WINDOW_MAXIMIZED (window))
+ window->saved_maximize = FALSE;
+
window->maximized_horizontally = FALSE;
meta_window_tile (window);
}
@@ -3439,7 +3451,7 @@ handle_run_terminal (MetaDisplay *display,
"keybinding press\n");
s = g_strdup_printf (_("No terminal command has been defined.\n"));
- error_on_command (-1, NULL, s, screen->number, event->xkey.time);
+ error_on_command (-1, NULL, s, screen->screen_name, event->xkey.time);
g_free (s);
return;
@@ -3448,7 +3460,7 @@ handle_run_terminal (MetaDisplay *display,
err = NULL;
if (!meta_spawn_command_line_async_on_screen (command, screen, &err))
{
- error_on_command (-1, command, err->message, screen->number,
+ error_on_command (-1, command, err->message, screen->screen_name,
event->xkey.time);
g_error_free (err);
diff --git a/src/core/place.c b/src/core/place.c
index 99cedd14..bcfafe42 100644
--- a/src/core/place.c
+++ b/src/core/place.c
@@ -87,6 +87,47 @@ northwestcmp (gconstpointer a, gconstpointer b)
return 0;
}
+static gboolean
+place_by_pointer(MetaWindow *window,
+ MetaFrameGeometry *fgeom,
+ MetaPlacementMode placement_mode,
+ int *new_x,
+ int *new_y)
+{
+ int window_width, window_height;
+ Window root_return, child_return;
+ int root_x_return, root_y_return;
+ int win_x_return, win_y_return;
+ unsigned int mask_return;
+
+ XQueryPointer (window->display->xdisplay,
+ window->screen->xroot,
+ &root_return,
+ &child_return,
+ &root_x_return,
+ &root_y_return,
+ &win_x_return,
+ &win_y_return,
+ &mask_return);
+
+ window_width = window->frame ? window->frame->rect.width : window->rect.width;
+ window_height = window->frame ? window->frame->rect.height : window->rect.height;
+
+ if (fgeom) {
+ *new_x = root_x_return + fgeom->left_width - window_width / 2;
+ *new_y = root_y_return + fgeom->top_height - window_height / 2;
+ }
+ else {
+ *new_x = root_x_return - window_width / 2;
+ *new_y = root_y_return - window_height / 2;
+ }
+
+ if (placement_mode == META_PLACEMENT_MODE_MANUAL)
+ window->move_after_placement = TRUE;
+
+ return TRUE;
+}
+
static void
find_next_cascade (MetaWindow *window,
MetaFrameGeometry *fgeom,
@@ -663,6 +704,7 @@ meta_window_place (MetaWindow *window,
{
GList *windows;
const MetaXineramaScreenInfo *xi;
+ MetaPlacementMode placement_mode;
/* frame member variables should NEVER be used in here, only
* MetaFrameGeometry. But remember fgeom == NULL
@@ -853,6 +895,16 @@ meta_window_place (MetaWindow *window,
x = xi->rect.x;
y = xi->rect.y;
+ /* Placement based on pointer position */
+ placement_mode = meta_prefs_get_placement_mode();
+
+ if (placement_mode == META_PLACEMENT_MODE_POINTER ||
+ placement_mode == META_PLACEMENT_MODE_MANUAL)
+ {
+ if (place_by_pointer (window, fgeom, placement_mode, &x, &y))
+ goto done_check_denied_focus;
+ }
+
if (find_first_fit (window, fgeom, windows,
xi->number,
x, y, &x, &y))
diff --git a/src/core/prefs.c b/src/core/prefs.c
index 8847614e..2f3e9392 100644
--- a/src/core/prefs.c
+++ b/src/core/prefs.c
@@ -162,10 +162,14 @@ static void button_layout_handler (MetaPreference, const gchar*, gboolean*);
static gboolean update_binding (MetaKeyPref *binding,
gchar *value);
-static void init_bindings (void);
+static void init_bindings (GSettings *);
+static void init_screen_bindings (void);
+static void init_window_bindings (void);
static void init_commands (void);
static void init_workspace_names (void);
+static MetaPlacementMode placement_mode = META_PLACEMENT_MODE_AUTOMATIC;
+
typedef struct
{
MetaPrefsChangedFunc func;
@@ -315,6 +319,11 @@ static MetaEnumPreference preferences_enum[] =
META_PREF_ACTION_RIGHT_CLICK_TITLEBAR,
(gint *) &action_right_click_titlebar,
},
+ { "placement-mode",
+ KEY_GENERAL_SCHEMA,
+ META_PREF_PLACEMENT_MODE,
+ (gint *) &placement_mode,
+ },
{ NULL, NULL, 0, NULL },
};
@@ -890,13 +899,6 @@ meta_prefs_init (void)
g_hash_table_insert (settings_schemas, KEY_MATE_TERMINAL_SCHEMA, settings_mate_terminal);
g_hash_table_insert (settings_schemas, KEY_MATE_MOUSE_SCHEMA, settings_mate_mouse);
- /* Pick up initial values. */
-
- handle_preference_init_enum ();
- handle_preference_init_bool ();
- handle_preference_init_string ();
- handle_preference_init_int ();
-
g_signal_connect (settings_general, "changed", G_CALLBACK (change_notify), NULL);
g_signal_connect (settings_command, "changed", G_CALLBACK (change_notify), NULL);
g_signal_connect (settings_screen_bindings, "changed", G_CALLBACK (change_notify), NULL);
@@ -909,7 +911,15 @@ meta_prefs_init (void)
g_signal_connect (settings_mate_mouse, "changed::" KEY_MATE_MOUSE_CURSOR_THEME, G_CALLBACK (change_notify), NULL);
g_signal_connect (settings_mate_mouse, "changed::" KEY_MATE_MOUSE_CURSOR_SIZE, G_CALLBACK (change_notify), NULL);
- init_bindings ();
+ /* Pick up initial values. */
+
+ handle_preference_init_enum ();
+ handle_preference_init_bool ();
+ handle_preference_init_string ();
+ handle_preference_init_int ();
+
+ init_screen_bindings ();
+ init_window_bindings ();
init_commands ();
init_workspace_names ();
}
@@ -972,7 +982,7 @@ change_notify (GSettings *settings,
g_free(str);
}
- else if (g_strcmp0 (schema_name, KEY_WORKSPACE_NAME_SCHEMA))
+ else if (g_strcmp0 (schema_name, KEY_WORKSPACE_NAME_SCHEMA) == 0)
{
gchar *str;
str = g_settings_get_string (settings, key);
@@ -1553,6 +1563,9 @@ meta_preference_to_string (MetaPreference pref)
case META_PREF_SIDE_BY_SIDE_TILING:
return "SIDE_BY_SIDE_TILING";
+
+ case META_PREF_PLACEMENT_MODE:
+ return "PLACEMENT_MODE";
}
return "(unknown)";
@@ -1582,32 +1595,32 @@ static MetaKeyPref key_bindings[] = {
#undef keybind
static void
-init_bindings (void)
+init_bindings (GSettings *settings)
{
- const char *prefix[] = {
- KEY_WINDOW_BINDINGS_SCHEMA,
- KEY_SCREEN_BINDINGS_SCHEMA,
- NULL
- };
- int i;
gchar **list = NULL;
gchar *str_val = NULL;
- GSettings *bindings_settings = NULL;
- for (i = 0; prefix[i]; i++)
+ list = g_settings_list_keys (settings);
+ while (*list != NULL)
{
- bindings_settings = g_settings_new (prefix [i]);
- list = g_settings_list_keys (bindings_settings);
- while (*list != NULL)
- {
- str_val = g_settings_get_string (bindings_settings, *list);
- update_key_binding (*list, str_val);
- list++;
- }
+ str_val = g_settings_get_string (settings, *list);
+ update_key_binding (*list, str_val);
+ list++;
}
+
g_free (str_val);
- g_object_unref (bindings_settings);
+}
+
+static void
+init_screen_bindings (void)
+{
+ init_bindings (settings_screen_bindings);
+}
+static void
+init_window_bindings (void)
+{
+ init_bindings (settings_window_bindings);
}
static void
@@ -1623,6 +1636,7 @@ init_commands (void)
update_command (*list, str_val);
list++;
}
+
g_free (str_val);
}
@@ -1639,6 +1653,7 @@ init_workspace_names (void)
update_workspace_name (*list, str_val);
list++;
}
+
g_free (str_val);
}
@@ -2236,6 +2251,12 @@ meta_prefs_get_force_fullscreen (void)
return force_fullscreen;
}
+MetaPlacementMode
+meta_prefs_get_placement_mode (void)
+{
+ return placement_mode;
+}
+
void
meta_prefs_set_force_compositing_manager (gboolean whether)
{
diff --git a/src/core/window-private.h b/src/core/window-private.h
index 20e619cb..0b3cf594 100644
--- a/src/core/window-private.h
+++ b/src/core/window-private.h
@@ -139,6 +139,9 @@ struct _MetaWindow
guint maximize_vertically_after_placement : 1;
guint minimize_after_placement : 1;
+ /* Whether to move after placement */
+ guint move_after_placement : 1;
+
/* The current or requested tile mode. If maximized_vertically is true,
* this is the current mode. If not, it is the mode which will be
* requested after the window grab is released */
diff --git a/src/core/window.c b/src/core/window.c
index 95d49885..30ebfa85 100644
--- a/src/core/window.c
+++ b/src/core/window.c
@@ -461,6 +461,7 @@ meta_window_new_with_attrs (MetaDisplay *display,
window->maximize_horizontally_after_placement = FALSE;
window->maximize_vertically_after_placement = FALSE;
window->minimize_after_placement = FALSE;
+ window->move_after_placement = FALSE;
window->fullscreen = FALSE;
window->fullscreen_after_placement = FALSE;
window->fullscreen_monitors[0] = -1;
@@ -2346,6 +2347,13 @@ meta_window_show (MetaWindow *window)
if (takes_focus_on_map)
{
meta_window_focus (window, timestamp);
+
+ if (window->move_after_placement)
+ {
+ meta_window_begin_grab_op(window, META_GRAB_OP_KEYBOARD_MOVING,
+ FALSE, timestamp);
+ window->move_after_placement = FALSE;
+ }
}
else
{
@@ -2670,14 +2678,9 @@ meta_window_maximize (MetaWindow *window,
if (window->tile_mode != META_TILE_NONE)
{
saved_rect = &window->saved_rect;
- window->maximized_vertically = FALSE;
- }
-
- if (window->tile_mode != META_TILE_NONE)
- {
- saved_rect = &window->saved_rect;
window->maximized_vertically = FALSE;
+ window->tile_mode = META_TILE_NONE;
}
meta_window_maximize_internal (window,
@@ -2751,7 +2754,7 @@ meta_window_can_tile (MetaWindow *window)
MetaRectangle tile_area;
/*if (!META_WINDOW_ALLOWS_RESIZE (window))*/
- if (!META_WINDOW_ALLOWS_RESIZE (window))
+ if (!meta_window_can_tile_maximized (window) || window->shaded)
return FALSE;
monitor = meta_screen_get_current_xinerama (window->screen);
@@ -2780,15 +2783,6 @@ meta_window_unmaximize (MetaWindow *window,
/* At least one of the two directions ought to be set */
gboolean unmaximize_horizontally, unmaximize_vertically;
- /* Restore tiling if necessary */
- if (window->tile_mode == META_TILE_LEFT ||
- window->tile_mode == META_TILE_RIGHT)
- {
- window->maximized_horizontally = FALSE;
- meta_window_tile (window);
- return;
- }
-
unmaximize_horizontally = directions & META_MAXIMIZE_HORIZONTAL;
unmaximize_vertically = directions & META_MAXIMIZE_VERTICAL;
g_assert (unmaximize_horizontally || unmaximize_vertically);
@@ -3333,6 +3327,7 @@ send_sync_request (MetaWindow *window)
ev.data.l[1] = meta_display_get_current_time (window->display);
ev.data.l[2] = XSyncValueLow32 (value);
ev.data.l[3] = XSyncValueHigh32 (value);
+ ev.data.l[4] = 0;
/* We don't need to trap errors here as we are already
* inside an error_trap_push()/pop() pair.
@@ -5194,8 +5189,7 @@ meta_window_client_message (MetaWindow *window,
{
meta_verbose ("WM_CHANGE_STATE client message, state: %ld\n",
event->xclient.data.l[0]);
- if (event->xclient.data.l[0] == IconicState &&
- window->has_minimize_func)
+ if (event->xclient.data.l[0] == IconicState)
meta_window_minimize (window);
return TRUE;
@@ -5599,6 +5593,8 @@ static gboolean
process_property_notify (MetaWindow *window,
XPropertyEvent *event)
{
+ Window xid = window->xwindow;
+
if (meta_is_verbose ()) /* avoid looking up the name if we don't have to */
{
char *property_name = XGetAtomName (window->display->xdisplay,
@@ -5609,7 +5605,13 @@ process_property_notify (MetaWindow *window,
XFree (property_name);
}
- meta_window_reload_property (window, event->atom, FALSE);
+ if (event->atom == window->display->atom__NET_WM_USER_TIME &&
+ window->user_time_window)
+ {
+ xid = window->user_time_window;
+ }
+
+ meta_window_reload_property_from_xwindow (window, xid, event->atom, FALSE);
return TRUE;
}
@@ -6735,8 +6737,8 @@ meta_window_show_menu (MetaWindow *window,
if (!window->has_maximize_func)
insensitive |= META_MENU_OP_UNMAXIMIZE | META_MENU_OP_MAXIMIZE;
- /*if (!window->has_minimize_func)
- insensitive |= META_MENU_OP_MINIMIZE;*/
+ if (!window->has_minimize_func)
+ insensitive |= META_MENU_OP_MINIMIZE;
/*if (!window->has_close_func)
insensitive |= META_MENU_OP_DELETE;*/
diff --git a/src/core/workspace.c b/src/core/workspace.c
index d61529d2..e2a397a0 100644
--- a/src/core/workspace.c
+++ b/src/core/workspace.c
@@ -382,6 +382,10 @@ meta_workspace_activate_with_focus (MetaWorkspace *workspace,
if (workspace->screen->active_workspace)
workspace_switch_sound(workspace->screen->active_workspace, workspace);
+ /* Free any cached pointers to the workspaces's edges from
+ * a current resize or move operation */
+ meta_display_cleanup_edges (workspace->screen->display);
+
/* Note that old can be NULL; e.g. when starting up */
old = workspace->screen->active_workspace;
@@ -545,6 +549,11 @@ meta_workspace_invalidate_work_area (MetaWorkspace *workspace)
"Invalidating work area for workspace %d\n",
meta_workspace_index (workspace));
+ /* If we are in the middle of a resize or move operation, we
+ * might have cached pointers to the workspace's edges */
+ if (workspace == workspace->screen->active_workspace)
+ meta_display_cleanup_edges (workspace->screen->display);
+
g_free (workspace->work_area_xinerama);
workspace->work_area_xinerama = NULL;
diff --git a/src/core/xprops.c b/src/core/xprops.c
index f9b4578a..a54e2185 100644
--- a/src/core/xprops.c
+++ b/src/core/xprops.c
@@ -264,6 +264,16 @@ cardinal_list_from_results (GetPropertyResults *results,
*n_cardinals_p = results->n_items;
results->prop = NULL;
+#if GLIB_SIZEOF_LONG == 8
+ /* Xlib sign-extends format=32 items, but we want them unsigned */
+ {
+ int i;
+
+ for (i = 0; i < *n_cardinals_p; i++)
+ (*cardinals_p)[i] = (*cardinals_p)[i] & 0xffffffff;
+ }
+#endif
+
return TRUE;
}
@@ -608,6 +618,10 @@ cardinal_with_atom_type_from_results (GetPropertyResults *results,
return FALSE;
*cardinal_p = *(gulong*) results->prop;
+#if GLIB_SIZEOF_LONG == 8
+ /* Xlib sign-extends format=32 items, but we want them unsigned */
+ *cardinal_p &= 0xffffffff;
+#endif
XFree (results->prop);
results->prop = NULL;
@@ -632,6 +646,29 @@ meta_prop_get_cardinal_with_atom_type (MetaDisplay *display,
return cardinal_with_atom_type_from_results (&results, prop_type, cardinal_p);
}
+static char *
+text_property_to_utf8 (Display *xdisplay,
+ const XTextProperty *prop)
+{
+ char *ret = NULL;
+ char **local_list = NULL;
+ int count = 0;
+ int res;
+
+ res = XmbTextPropertyToTextList (xdisplay, prop, &local_list, &count);
+ if (res == XNoMemory || res == XLocaleNotSupported || res == XConverterNotFound)
+ goto out;
+
+ if (count == 0)
+ goto out;
+
+ ret = g_strdup (local_list[0]);
+
+ out:
+ meta_XFree (local_list);
+ return ret;
+}
+
static gboolean
text_property_from_results (GetPropertyResults *results,
char **utf8_str_p)
@@ -646,8 +683,7 @@ text_property_from_results (GetPropertyResults *results,
tp.format = results->format;
tp.nitems = results->n_items;
- *utf8_str_p = meta_text_property_to_utf8 (results->display->xdisplay,
- &tp);
+ *utf8_str_p = text_property_to_utf8 (results->display->xdisplay, &tp);
if (tp.value != NULL)
XFree (tp.value);