Skip to content
Permalink
Browse files

* src/misc.h, src/misc.c, src/screen.h, src/screen.c, src/events.c,

	  src/menu.c, src/tabwin.c, src/placement.c, src/client.c, 
	  src/moveresize.c, src/netwm.c: Need to invalidate our internal 
	  monitor caching when adding/removing monitors with randr 1.2 
 

(Old svn revision: 29263)
  • Loading branch information...
Olivier Fourdan
Olivier Fourdan committed Jan 16, 2009
1 parent 80c97d8 commit 2c3371026c26e102b5f0115ef9307bdaa4dfa7f2
Showing with 116 additions and 83 deletions.
  1. +7 −0 ChangeLog
  2. +5 −0 NEWS
  3. +2 −2 src/client.c
  4. +19 −7 src/events.c
  5. +1 −1 src/menu.c
  6. +0 −61 src/misc.c
  7. +0 −3 src/misc.h
  8. +2 −2 src/moveresize.c
  9. +2 −2 src/netwm.c
  10. +4 −4 src/placement.c
  11. +65 −0 src/screen.c
  12. +8 −0 src/screen.h
  13. +1 −1 src/tabwin.c
@@ -1,3 +1,10 @@
2009-01-16 olivier

* src/misc.h, src/misc.c, src/screen.h, src/screen.c, src/events.c,
src/menu.c, src/tabwin.c, src/placement.c, src/client.c,
src/moveresize.c, src/netwm.c: Need to invalidate our internal
monitor caching when adding/removing monitors with randr 1.2

2009-01-14 jannis

* configure.in.in: Post-release version bump.
5 NEWS
@@ -1,6 +1,11 @@
4.5.99.1 (Xfce 4.6rc1)
======================

- Fix a crash when removing a monitor with xrandr 1.2

4.5.93 (Xfce 4.6beta3)
======================

- Work around a problem affecting the use of the "Super" key as modifier for
moving windows (Bug #4632).
- Fix smart placement not working for windows with height or width larger than
@@ -2989,7 +2989,7 @@ void clientToggleFullscreen (Client * c)
cx = frameX (c) + (frameWidth (c) / 2);
cy = frameY (c) + (frameHeight (c) / 2);

monitor_nbr = find_monitor_at_point (c->screen_info->gscr, cx, cy);
monitor_nbr = myScreenFindMonitorAtPoint (c->screen_info, cx, cy);
gdk_screen_get_monitor_geometry (c->screen_info->gscr, monitor_nbr, &rect);

if ((c->size->max_width < rect.width) || (c->size->max_height < rect.height))
@@ -3129,7 +3129,7 @@ clientNewMaxSize (Client * c, XWindowChanges *wc)

screen_info = c->screen_info;

monitor_nbr = find_monitor_at_point (screen_info->gscr, cx, cy);
monitor_nbr = myScreenFindMonitorAtPoint (screen_info, cx, cy);
gdk_screen_get_monitor_geometry (screen_info->gscr, monitor_nbr, &rect);

full_x = MAX (screen_info->params->xfwm_margins[STRUTS_LEFT], rect.x);
@@ -2736,14 +2736,26 @@ size_changed_cb(GdkScreen *gscreen, gpointer data)
static void
monitors_changed_cb(GdkScreen *gscreen, gpointer data)
{
ScreenInfo *screen_info;

TRACE ("entering monitors_changed_cb");

screen_info = (ScreenInfo *) data;
g_return_if_fail (screen_info);

/* We have added/removed a monitor or even changed the layout,
* the cache for monitor position we use in our screen structure
* is not valid anymore and potentially refers to a monitor that
* was just removed, so invalidate it.
*/
screen_info->cache_monitor = -1;

/*
* From the window manager point of view,
* a XRand 1.2 monitor change is similar to
* a screen size change.
*/
size_changed_cb(gscreen, data);
size_changed_cb (gscreen, data);
}

void
@@ -2756,15 +2768,15 @@ initGtkCallbacks (ScreenInfo *screen_info)
"button_press_event", GTK_SIGNAL_FUNC (show_popup_cb), (gpointer) NULL);
g_signal_connect (GTK_OBJECT (myScreenGetGtkWidget (screen_info)), "client_event",
GTK_SIGNAL_FUNC (client_event_cb), (gpointer) (screen_info->display_info));
g_signal_connect(G_OBJECT(screen_info->gscr), "size-changed",
G_CALLBACK(size_changed_cb),
(gpointer) (screen_info));
g_signal_connect (G_OBJECT(screen_info->gscr), "size-changed",
G_CALLBACK(size_changed_cb),
(gpointer) (screen_info));
if(gtk_major_version > 2 || (gtk_major_version == 2 && gtk_minor_version >= 13))
{
TRACE ("connect \"monitors-changed\" cb");
g_signal_connect(G_OBJECT(screen_info->gscr), "monitors-changed",
G_CALLBACK(monitors_changed_cb),
(gpointer) (screen_info));
g_signal_connect (G_OBJECT(screen_info->gscr), "monitors-changed",
G_CALLBACK(monitors_changed_cb),
(gpointer) (screen_info));
}

settings = gtk_settings_get_default ();
@@ -126,7 +126,7 @@ popup_position_func (GtkMenu * menu, gint * x, gint * y, gboolean * push_in,
}

screen = gtk_widget_get_screen (GTK_WIDGET(menu));
monitor = find_monitor_at_point (screen, *x, *y);
monitor = gdk_screen_get_monitor_at_point (screen, *x, *y);
gtk_menu_set_monitor (GTK_MENU (menu), monitor);

g_free (user_data);
@@ -235,67 +235,6 @@ placeSidewalks(ScreenInfo *screen_info, gboolean activate)
}
}

/*
gdk_screen_get_monitor_at_point () doesn't give accurate results
when the point is off screen, use my own implementation from xfce 3
*/
gint
find_monitor_at_point (GdkScreen *screen, gint x, gint y)
{
static gint cache_monitor = -1;
static gint cache_x, cache_y;
gint dx, dy, center_x, center_y;
guint32 distsquare, min_distsquare;
gint num_monitors, nearest_monitor, i;
GdkRectangle monitor;

g_return_val_if_fail (GDK_IS_SCREEN (screen), -1);

/* Cache system */
if ((cache_monitor >= 0) && (x == cache_x) && (y == cache_y))
{
return (cache_monitor);
}

cache_x = x;
cache_y = y;

/* No monitor has been eligible, use the closest one */

min_distsquare = ((guint32) 0xffffffff);
nearest_monitor = 0;

num_monitors = gdk_screen_get_n_monitors (screen);
for (i = 0; i < num_monitors; i++)
{
gdk_screen_get_monitor_geometry (screen, i, &monitor);

if ((x >= monitor.x) && (x < monitor.x + monitor.width) &&
(y >= monitor.y) && (y < (monitor.y + monitor.height)))
{
cache_monitor = i;
return i;
}

center_x = monitor.x + (monitor.width / 2);
center_y = monitor.y + (monitor.height / 2);

dx = x - center_x;
dy = y - center_y;

distsquare = (dx * dx) + (dy * dy);

if (distsquare < min_distsquare)
{
min_distsquare = distsquare;
nearest_monitor = i;
}
}

cache_monitor = nearest_monitor;
return (nearest_monitor);
}

gchar*
get_atom_name (DisplayInfo *display_info, Atom atom)
{
@@ -70,9 +70,6 @@ gboolean checkWindowOnRoot (ScreenInfo *,
Window);
void placeSidewalks (ScreenInfo *,
gboolean);
gint find_monitor_at_point (GdkScreen *,
gint,
gint);
gchar* get_atom_name (DisplayInfo *,
Atom);

@@ -405,7 +405,7 @@ clientSnapPosition (Client * c, int prev_x, int prev_y)
best_frame_x = frame_x;
best_frame_y = frame_y;

monitor_nbr = find_monitor_at_point (screen_info->gscr, cx, cy);
monitor_nbr = myScreenFindMonitorAtPoint (screen_info, cx, cy);
gdk_screen_get_monitor_geometry (screen_info->gscr, monitor_nbr, &rect);

disp_x = rect.x;
@@ -1149,7 +1149,7 @@ clientResizeEventFilter (XEvent * xevent, gpointer data)
|| (passdata->handle == CORNER_COUNT + SIDE_LEFT)) ?
1 : 0;

monitor_nbr = find_monitor_at_point (screen_info->gscr, cx, cy);
monitor_nbr = myScreenFindMonitorAtPoint (screen_info, cx, cy);
gdk_screen_get_monitor_geometry (screen_info->gscr, monitor_nbr, &rect);

disp_x = rect.x;
@@ -747,8 +747,8 @@ clientUpdateFullscreenState (Client * c)
cx = frameX (c) + (frameWidth (c) / 2);
cy = frameY (c) + (frameHeight (c) / 2);

monitor_nbr = find_monitor_at_point (c->screen_info->gscr, cx, cy);
gdk_screen_get_monitor_geometry (c->screen_info->gscr, monitor_nbr, &rect);
monitor_nbr = myScreenFindMonitorAtPoint (screen_info, cx, cy);
gdk_screen_get_monitor_geometry (screen_info->gscr, monitor_nbr, &rect);

c->fullscreen_old_x = c->x;
c->fullscreen_old_y = c->y;
@@ -225,7 +225,7 @@ clientConstrainPos (Client * c, gboolean show_full)
cy = frame_y + (frame_height / 2);

screen_info = c->screen_info;
monitor_nbr = find_monitor_at_point (screen_info->gscr, cx, cy);
monitor_nbr = myScreenFindMonitorAtPoint (screen_info, cx, cy);
gdk_screen_get_monitor_geometry (screen_info->gscr, monitor_nbr, &rect);

screen_width = screen_info->width;
@@ -668,7 +668,7 @@ clientInitPosition (Client * c)
if ((n_monitors > 1) || (screen_info->params->placement_mode == PLACE_MOUSE))
{
getMouseXY (screen_info, screen_info->xroot, &msx, &msy);
monitor_nbr = find_monitor_at_point (screen_info->gscr, msx, msy);
monitor_nbr = myScreenFindMonitorAtPoint (screen_info, msx, msy);
}
gdk_screen_get_monitor_geometry (screen_info->gscr, monitor_nbr, &rect);

@@ -684,7 +684,7 @@ clientInitPosition (Client * c)
{
msx = frameX (c) + (frameWidth (c) / 2);
msy = frameY (c) + (frameHeight (c) / 2);
monitor_nbr = find_monitor_at_point (screen_info->gscr, msx, msy);
monitor_nbr = myScreenFindMonitorAtPoint (screen_info, msx, msy);
gdk_screen_get_monitor_geometry (screen_info->gscr, monitor_nbr, &rect);
}
}
@@ -888,7 +888,7 @@ clientFill (Client * c, int fill_type)
cx = tmp_x + (tmp_w / 2);
cy = tmp_y + (tmp_h / 2);

monitor_nbr = find_monitor_at_point (screen_info->gscr, cx, cy);
monitor_nbr = myScreenFindMonitorAtPoint (screen_info, cx, cy);
gdk_screen_get_monitor_geometry (screen_info->gscr, monitor_nbr, &rect);

full_x = MAX (screen_info->params->xfwm_margins[STRUTS_LEFT], rect.x);
@@ -221,6 +221,10 @@ myScreenInit (DisplayInfo *display_info, GdkScreen *gscr, unsigned long event_ma
screen_info->key_grabs = 0;
screen_info->pointer_grabs = 0;

screen_info->cache_monitor = -1;
screen_info->cache_x = 0;
screen_info->cache_y =0;

getHint (display_info, screen_info->xroot, NET_SHOWING_DESKTOP, &desktop_visible);
screen_info->show_desktop = (desktop_visible != 0);

@@ -561,3 +565,64 @@ myScreenGetClientFromWindow (ScreenInfo *screen_info, Window w, unsigned short m

return NULL;
}

/*
gdk_screen_get_monitor_at_point () doesn't give accurate results
when the point is off screen, use my own implementation from xfce 3
*/
gint
myScreenFindMonitorAtPoint (ScreenInfo *screen_info, gint x, gint y)
{
gint dx, dy, center_x, center_y;
guint32 distsquare, min_distsquare;
gint num_monitors, nearest_monitor, i;
GdkRectangle monitor;

g_return_val_if_fail (screen_info != NULL, 0);
g_return_val_if_fail (GDK_IS_SCREEN (screen_info->gscr), 0);

/* Cache system */
if ((screen_info->cache_monitor >= 0) &&
(x == screen_info->cache_x) && (y == screen_info->cache_y))
{
return (screen_info->cache_monitor);
}

screen_info->cache_x = x;
screen_info->cache_y = y;

/* No monitor has been eligible, use the closest one */

min_distsquare = ((guint32) 0xffffffff);
nearest_monitor = 0;

num_monitors = gdk_screen_get_n_monitors (screen_info->gscr);
for (i = 0; i < num_monitors; i++)
{
gdk_screen_get_monitor_geometry (screen_info->gscr, i, &monitor);

if ((x >= monitor.x) && (x < monitor.x + monitor.width) &&
(y >= monitor.y) && (y < (monitor.y + monitor.height)))
{
screen_info->cache_monitor = i;
return i;
}

center_x = monitor.x + (monitor.width / 2);
center_y = monitor.y + (monitor.height / 2);

dx = x - center_x;
dy = y - center_y;

distsquare = (dx * dx) + (dy * dy);

if (distsquare < min_distsquare)
{
min_distsquare = distsquare;
nearest_monitor = i;
}
}

screen_info->cache_monitor = nearest_monitor;
return (nearest_monitor);
}
@@ -115,6 +115,11 @@ struct _ScreenInfo
int current_ws;
int previous_ws;

/* Monitor search caching */
gint cache_monitor;
gint cache_x;
gint cache_y;

/* Workspace definitions */
int workspace_count;
gchar **workspace_names;
@@ -210,5 +215,8 @@ int myScreenGetKeyPressed (ScreenInfo *,
Client *myScreenGetClientFromWindow (ScreenInfo *,
Window,
unsigned short);
gint myScreenFindMonitorAtPoint (ScreenInfo *,
gint,
gint);

#endif /* INC_SCREEN_H */
@@ -217,7 +217,7 @@ createWindowlist (GdkScreen * scr, Client * current, Client * new, unsigned int
g_return_val_if_fail (n_clients > 0, NULL);

getMouseXY (screen_info, screen_info->xroot, &msx, &msy);
monitor = find_monitor_at_point (scr, msx, msy);
monitor = myScreenFindMonitorAtPoint (screen_info, msx, msy);
gdk_screen_get_monitor_geometry (scr, monitor, &monitor_sz);

/* add the width of the border on each side */

0 comments on commit 2c33710

Please sign in to comment.
You can’t perform that action at this time.