2 * screen.c - screen management
4 * Copyright © 2007 Julien Danjou <julien@danjou.info>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
27 extern Client
*sel
, *clients
;
30 * \param disp Display ref
31 * \param screen Screen number
32 * \param statusbar statusbar
33 * \return ScreenInfo struct array with all screens info
36 get_screen_info(Display
*disp
, int screen
, Statusbar
*statusbar
)
38 int i
, screen_number
= 0;
41 if(XineramaIsActive(disp
))
42 si
= XineramaQueryScreens(disp
, &screen_number
);
45 /* emulate Xinerama info but only fill the screen we want */
46 si
= p_new(ScreenInfo
, screen
+ 1);
47 si
[screen
].width
= DisplayWidth(disp
, screen
);
48 si
[screen
].height
= DisplayHeight(disp
, screen
);
51 screen_number
= screen
+ 1;
55 for(i
= 0; i
< screen_number
; i
++)
57 if(statusbar
->position
== BarTop
58 || statusbar
->position
== BarBot
)
59 si
[i
].height
-= statusbar
->height
;
60 if(statusbar
->position
== BarTop
)
61 si
[i
].y_org
+= statusbar
->height
;
68 * \param disp Display ref
69 * \param screen Screen number
70 * \param statusbar the statusbar
71 * \return ScreenInfo struct pointer with all display info
74 get_display_info(Display
*disp
, int screen
, Statusbar
*statusbar
)
78 si
= p_new(ScreenInfo
, 1);
81 si
->y_org
= statusbar
&& statusbar
->position
== BarTop
? statusbar
->height
: 0;
82 si
->width
= DisplayWidth(disp
, screen
);
83 si
->height
= DisplayHeight(disp
, screen
) -
84 (statusbar
&& (statusbar
->position
== BarTop
|| statusbar
->position
== BarBot
) ? statusbar
->height
: 0);
89 /** Return the Xinerama screen number where the coordinates belongs to
90 * \param disp Display ref
91 * \param x x coordinate of the window
92 * \param y y coordinate of the window
93 * \return screen number or DefaultScreen of disp on no match
96 get_screen_bycoord(Display
*disp
, int x
, int y
)
101 /* don't waste our time */
102 if(!XineramaIsActive(disp
))
103 return DefaultScreen(disp
);
105 si
= get_screen_info(disp
, 0, NULL
);
107 for(i
= 0; i
< get_screen_count(disp
); i
++)
108 if(x
>= si
[i
].x_org
&& x
< si
[i
].x_org
+ si
[i
].width
109 && y
>= si
[i
].y_org
&& y
< si
[i
].y_org
+ si
[i
].height
)
116 return DefaultScreen(disp
);
119 /** Return the actual screen count
120 * \param disp Display ref
121 * \return the number of screen available
124 get_screen_count(Display
*disp
)
128 if(XineramaIsActive(disp
))
129 XineramaQueryScreens(disp
, &screen_number
);
131 return ScreenCount(disp
);
133 return screen_number
;
136 /** This returns the real X screen number for a logical
137 * screen if Xinerama is active.
138 * \param disp Display ref
139 * \param screen the logical screen
140 * \return the X screen
143 get_phys_screen(Display
*disp
, int screen
)
145 if(XineramaIsActive(disp
))
146 return DefaultScreen(disp
);
150 /** Move a client to a virtual screen
151 * \param c the client
152 * \param acf_new the awesome_config for the new screen
153 * \param doresize set to True if we also move the client to the new x_org and
154 * y_org of the new screen
157 move_client_to_screen(Client
*c
, awesome_config
*acf_new
, Bool doresize
)
162 c
->screen
= acf_new
->screen
;
163 p_realloc(&c
->tags
, acf_new
->ntags
);
164 for(i
= 0; i
< acf_new
->ntags
; i
++)
165 c
->tags
[i
] = acf_new
->tags
[i
].selected
;
167 si
= get_screen_info(c
->display
, c
->screen
, &acf_new
->statusbar
);
168 c
->rx
= si
[c
->screen
].x_org
;
169 c
->ry
= si
[c
->screen
].y_org
;
171 resize(c
, c
->rx
, c
->ry
, c
->rw
, c
->rh
, acf_new
, True
);
176 move_mouse_pointer_to_screen(Display
*disp
, int screen
)
178 if(XineramaIsActive(disp
))
180 ScreenInfo
*si
= get_screen_info(disp
, screen
, NULL
);
181 XWarpPointer(disp
, None
, DefaultRootWindow(disp
), 0, 0, 0, 0, si
[screen
].x_org
, si
[screen
].y_org
);
185 XWarpPointer(disp
, None
, RootWindow(disp
, screen
), 0, 0, 0, 0, 0, 0);
189 uicb_focusnextscreen(Display
*disp
,
191 awesome_config
* awesomeconf
,
192 const char *arg
__attribute__ ((unused
)))
195 int next_screen
= awesomeconf
->screen
+ 1 >= get_screen_count(disp
) ? 0 : awesomeconf
->screen
+ 1;
197 for(c
= clients
; c
&& !isvisible(c
, next_screen
, awesomeconf
[next_screen
- awesomeconf
->screen
].tags
, awesomeconf
[next_screen
- awesomeconf
->screen
].ntags
); c
= c
->next
);
200 focus(c
->display
, &drawcontext
[next_screen
- awesomeconf
->screen
], c
, True
, &awesomeconf
[next_screen
- awesomeconf
->screen
]);
201 restack(c
->display
, &drawcontext
[next_screen
- awesomeconf
->screen
], &awesomeconf
[next_screen
- awesomeconf
->screen
]);
203 move_mouse_pointer_to_screen(disp
, next_screen
);
207 uicb_focusprevscreen(Display
*disp
,
209 awesome_config
* awesomeconf
,
210 const char *arg
__attribute__ ((unused
)))
213 int prev_screen
= awesomeconf
->screen
- 1 < 0 ? get_screen_count(disp
) - 1 : awesomeconf
->screen
- 1;
215 for(c
= clients
; c
&& !isvisible(c
, prev_screen
, awesomeconf
[prev_screen
- awesomeconf
->screen
].tags
, awesomeconf
[prev_screen
- awesomeconf
->screen
].ntags
); c
= c
->next
);
218 focus(c
->display
, &drawcontext
[prev_screen
- awesomeconf
->screen
], c
, True
, &awesomeconf
[prev_screen
- awesomeconf
->screen
]);
219 restack(c
->display
, &drawcontext
[prev_screen
- awesomeconf
->screen
], &awesomeconf
[prev_screen
- awesomeconf
->screen
]);
221 move_mouse_pointer_to_screen(disp
, prev_screen
);
224 /** Move client to a virtual screen (if Xinerama is active)
225 * \param disp Display ref
226 * \param drawcontext drawcontext ref
227 * \param awesomeconf awesome config
228 * \param arg screen number
229 * \ingroup ui_callback
232 uicb_movetoscreen(Display
*disp
,
234 awesome_config
* awesomeconf
,
237 int new_screen
, prev_screen
;
239 if(!XineramaIsActive(disp
) || !sel
)
244 new_screen
= strtol(arg
, NULL
, 10);
245 if(new_screen
>= get_screen_count(disp
) || new_screen
< 0)
249 new_screen
= sel
->screen
+ 1 >= get_screen_count(disp
) ? 0 : sel
->screen
+ 1;
251 prev_screen
= sel
->screen
;
252 move_client_to_screen(sel
, &awesomeconf
[new_screen
- awesomeconf
->screen
], True
);
253 move_mouse_pointer_to_screen(disp
, new_screen
);
254 arrange(disp
, drawcontext
, &awesomeconf
[prev_screen
- awesomeconf
->screen
]);
255 arrange(disp
, &drawcontext
[new_screen
- awesomeconf
->screen
], &awesomeconf
[new_screen
- awesomeconf
->screen
]);