Commit 12f255e1 authored by Steve Frécinaux's avatar Steve Frécinaux

Fix bug #484613 by adding viewport support to gedit.

Gedit now openw the document in the right viewport when using a
viewport-based WM

Previously, the document was always opened on the first viewport in such
a window manager (say, compiz). Fixes bug #484613.

svn path=/trunk/; revision=5988
parent aada2ea6
2007-10-28 Steve Frécinaux <code@istique.net>
Fix bug #484613 by adding viewport support to gedit.
* gedit/gedit-utils.[ch]: New utility function
gedit_utils_get_current_viewport().
* gedit/gedit-app.[ch]: Rename gedit_app_get_window_in_workspace() into
gedit_app_get_window_in_viewport and add viewport support to it.
* gedit/gedit.c: Adapt IPC protocol to specify the current viewport to
the running instance.
2007-10-28 Paolo Borelli <pborelli@katamail.com>
* gedit/gedit-utils.[ch]:
......
......@@ -399,9 +399,11 @@ gedit_app_get_active_window (GeditApp *app)
}
static gboolean
is_in_workspace (GeditWindow *window,
GdkScreen *screen,
gint workspace)
is_in_viewport (GeditWindow *window,
GdkScreen *screen,
gint workspace,
gint viewport_x,
gint viewport_y)
{
GdkScreen *s;
GdkDisplay *display;
......@@ -410,7 +412,11 @@ is_in_workspace (GeditWindow *window,
gint cur_n;
gint n;
gint ws;
gint sc_width, sc_height;
gint x, y, width, height;
gint vp_x, vp_y;
/* Check for screen and display match */
display = gdk_screen_get_display (screen);
cur_name = gdk_display_get_name (display);
cur_n = gdk_screen_get_number (screen);
......@@ -420,16 +426,50 @@ is_in_workspace (GeditWindow *window,
name = gdk_display_get_name (display);
n = gdk_screen_get_number (s);
ws = gedit_utils_get_window_workspace (GTK_WINDOW (window));
if (strcmp (cur_name, name) != 0 || cur_n != n)
return FALSE;
return ((strcmp (cur_name, name) == 0) && cur_n == n &&
(ws == workspace || ws == GEDIT_ALL_WORKSPACES));
/* Check for workspace match */
ws = gedit_utils_get_window_workspace (GTK_WINDOW (window));
if (ws != workspace && ws != GEDIT_ALL_WORKSPACES)
return FALSE;
/* Check for viewport match */
gdk_window_get_position (GTK_WIDGET (window)->window, &x, &y);
gdk_drawable_get_size (GTK_WIDGET (window)->window, &width, &height);
gedit_utils_get_current_viewport (screen, &vp_x, &vp_y);
x += vp_x;
y += vp_y;
sc_width = gdk_screen_get_width (screen);
sc_height = gdk_screen_get_height (screen);
return x + width * .25 >= viewport_x &&
x + width * .75 < viewport_x + sc_width &&
y >= viewport_y &&
y + height < viewport_y + sc_height;
}
/**
* _gedit_app_get_window_in_viewport
* @app: the #GeditApp
* @screen: the #GdkScreen
* @workspace: the workspace number
* @viewport_x: the viewport horizontal origin
* @viewport_y: the viewport vertical origin
*
* Since a workspace can be larger than the screen, it is divided into several
* equal parts called viewports. This function retrives the #GeditWindow in
* the given viewport of the given workspace.
*
* Return value: the #GeditWindow in the given viewport of the given workspace.
*/
GeditWindow *
_gedit_app_get_window_in_workspace (GeditApp *app,
GdkScreen *screen,
gint workspace)
_gedit_app_get_window_in_viewport (GeditApp *app,
GdkScreen *screen,
gint workspace,
gint viewport_x,
gint viewport_y)
{
GeditWindow *window;
......@@ -442,7 +482,7 @@ _gedit_app_get_window_in_workspace (GeditApp *app,
g_return_val_if_fail (GEDIT_IS_WINDOW (window), NULL);
if (is_in_workspace (window, screen, workspace))
if (is_in_viewport (window, screen, workspace, viewport_x, viewport_y))
return window;
/* otherwise try to see if there is a window on this workspace */
......@@ -450,7 +490,7 @@ _gedit_app_get_window_in_workspace (GeditApp *app,
{
window = l->data;
if (is_in_workspace (window, screen, workspace))
if (is_in_viewport (window, screen, workspace, viewport_x, viewport_y))
return window;
}
......
......@@ -112,9 +112,11 @@ GeditLockdownMask gedit_app_get_lockdown (GeditApp *app);
*/
GeditWindow *_gedit_app_restore_window (GeditApp *app,
const gchar *role);
GeditWindow *_gedit_app_get_window_in_workspace (GeditApp *app,
GdkScreen *screen,
gint workspace);
GeditWindow *_gedit_app_get_window_in_viewport (GeditApp *app,
GdkScreen *screen,
gint workspace,
gint viewport_x,
gint viewport_y);
void _gedit_app_set_lockdown (GeditApp *app,
GeditLockdownMask lockdown);
void _gedit_app_set_lockdown_bit (GeditApp *app,
......
......@@ -858,6 +858,59 @@ gedit_utils_get_window_workspace (GtkWindow *gtkwindow)
return ret;
}
/**
* gedit_utils_get_current_viewport: Get the current viewport origin
*
* Get the currently visible viewport origin for the #GdkScreen.
*
* If the X11 window property isn't found, (0, 0) is returned.
*/
void
gedit_utils_get_current_viewport (GdkScreen *screen,
gint *x,
gint *y)
{
GdkWindow *root_win;
GdkDisplay *display;
Atom type;
gint format;
gulong nitems;
gulong bytes_after;
gulong *coordinates;
gint err, result;
g_return_if_fail (GDK_IS_SCREEN (screen));
g_return_if_fail (x != NULL && y != NULL);
/* Default values for the viewport origin */
*x = 0;
*y = 0;
root_win = gdk_screen_get_root_window (screen);
display = gdk_screen_get_display (screen);
gdk_error_trap_push ();
result = XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XID (root_win),
gdk_x11_get_xatom_by_name_for_display (display, "_NET_DESKTOP_VIEWPORT"),
0, G_MAXLONG, False, XA_CARDINAL, &type, &format, &nitems,
&bytes_after, (void*) &coordinates);
err = gdk_error_trap_pop ();
if (err != Success || result != Success)
return;
if (type != XA_CARDINAL || format != 32 || nitems < 2)
{
XFree (coordinates);
return;
}
*x = coordinates[0];
*y = coordinates[1];
XFree (coordinates);
}
void
gedit_utils_activate_url (GtkAboutDialog *about,
const gchar *url,
......
......@@ -123,6 +123,10 @@ guint gedit_utils_get_current_workspace (GdkScreen *screen);
guint gedit_utils_get_window_workspace (GtkWindow *gtkwindow);
void gedit_utils_get_current_viewport (GdkScreen *screen,
gint *x,
gint *y);
void gedit_utils_activate_url (GtkAboutDialog *about,
const gchar *url,
gpointer data);
......
......@@ -198,6 +198,8 @@ on_message_received (const char *message,
gchar **commands;
gchar **params;
gint workspace;
gint viewport_x;
gint viewport_y;
gchar *display_name;
gint screen_number;
gint i;
......@@ -213,11 +215,13 @@ on_message_received (const char *message,
commands = g_strsplit (message, "\v", -1);
/* header */
params = g_strsplit (commands[0], "\t", 4);
params = g_strsplit (commands[0], "\t", 6);
startup_timestamp = atoi (params[0]);
display_name = params[1];
screen_number = atoi (params[2]);
workspace = atoi (params[3]);
viewport_x = atoi (params[4]);
viewport_y = atoi (params[5]);
display = display_open_if_needed (display_name);
if (display == NULL)
......@@ -283,9 +287,11 @@ on_message_received (const char *message,
else
{
/* get a window in the current workspace (if exists) and raise it */
window = _gedit_app_get_window_in_workspace (app,
screen,
workspace);
window = _gedit_app_get_window_in_viewport (app,
screen,
workspace,
viewport_x,
viewport_y);
}
if (file_list != NULL)
......@@ -349,11 +355,13 @@ send_bacon_message (void)
const gchar *display_name;
gint screen_number;
gint ws;
gint viewport_x;
gint viewport_y;
GString *command;
/* the messages have the following format:
* <--- header ---> <---- body ----->
* timestamp \t display_name \t screen_number \t workspace \v OP1 \t arg \t arg \v OP2 \t arg \t arg|...
* <--- header ---> <---- body ----->
* timestamp \t display_name \t screen_number \t workspace \t viewport_x \t viewport_y \v OP1 \t arg \t arg \v OP2 \t arg \t arg|...
*
* when the arg is a list of uri, they are separated by a space.
* So the delimiters are \v for the commands, \t for the tokens in
......@@ -373,16 +381,19 @@ send_bacon_message (void)
gedit_debug_message (DEBUG_APP, "Screen: %d", screen_number);
ws = gedit_utils_get_current_workspace (screen);
gedit_utils_get_current_viewport (screen, &viewport_x, &viewport_y);
command = g_string_new (NULL);
/* header */
g_string_append_printf (command,
"%" G_GUINT32_FORMAT "\t%s\t%d\t%d",
"%" G_GUINT32_FORMAT "\t%s\t%d\t%d\t%d\t%d",
startup_timestamp,
display_name,
screen_number,
ws);
ws,
viewport_x,
viewport_y);
/* NEW-WINDOW command */
if (new_window_option)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment