1 ---------------------------------------------------------------------------
2 -- @author Julien Danjou <julien@danjou.info>
3 -- @copyright 2009 Julien Danjou
4 -- @release @AWESOME_VERSION@
5 ---------------------------------------------------------------------------
7 local setmetatable
= setmetatable
12 local atag
= require("awful.tag")
14 --- Implements EWMH requests handling.
18 local data
= setmetatable({}, { __mode
= 'k' })
20 local function store_geometry(window
, reqtype
)
21 if not data
[window
] then data
[window
] = {} end
22 if not data
[window
][reqtype
] then data
[window
][reqtype
] = {} end
23 data
[window
][reqtype
] = window
:geometry()
24 data
[window
][reqtype
].screen
= window
.screen
27 -- Maximize a window horizontally.
28 -- @param window The window.
29 -- @param set Set or unset the maximized values.
30 local function maximized_horizontal(window
, set
)
32 store_geometry(window
, "maximized_horizontal")
33 local g
= screen
[window
.screen
].workarea
34 local bw
= window
.border_width
or 0
35 window
:geometry
{ width
= g
.width
- 2*bw
, x
= g
.x
}
36 elseif data
[window
] and data
[window
].maximized_horizontal
37 and data
[window
].maximized_horizontal
.x
38 and data
[window
].maximized_horizontal
.width
then
39 local g
= data
[window
].maximized_horizontal
40 window
:geometry
{ width
= g
.width
, x
= g
.x
}
44 -- Maximize a window vertically.
45 -- @param window The window.
46 -- @param set Set or unset the maximized values.
47 local function maximized_vertical(window
, set
)
49 store_geometry(window
, "maximized_vertical")
50 local g
= screen
[window
.screen
].workarea
51 local bw
= window
.border_width
or 0
52 window
:geometry
{ height
= g
.height
- 2*bw
, y
= g
.y
}
53 elseif data
[window
] and data
[window
].maximized_vertical
54 and data
[window
].maximized_vertical
.y
55 and data
[window
].maximized_vertical
.height
then
56 local g
= data
[window
].maximized_vertical
57 window
:geometry
{ height
= g
.height
, y
= g
.y
}
61 -- Fullscreen a window.
62 -- @param window The window.
63 -- @param set Set or unset the fullscreen values.
64 local function fullscreen(window
, set
)
66 store_geometry(window
, "fullscreen")
67 data
[window
].fullscreen
.border_width
= window
.border_width
68 local g
= screen
[window
.screen
].geometry
69 window
:geometry(screen
[window
.screen
].geometry
)
70 window
.border_width
= 0
71 elseif data
[window
] and data
[window
].fullscreen
then
72 window
:geometry(data
[window
].fullscreen
)
73 window
.border_width
= data
[window
].fullscreen
.border_width
77 local function screen_change(window
)
79 for _
, reqtype
in ipairs({ "maximized_vertical", "maximized_horizontal", "fullscreen" }) do
80 if data
[window
][reqtype
] then
81 if data
[window
][reqtype
].width
then
82 data
[window
][reqtype
].width
= math
.min(data
[window
][reqtype
].width
,
83 screen
[window
.screen
].workarea
.width
)
84 if reqtype
== "maximized_horizontal" then
85 local bw
= window
.border_width
or 0
86 data
[window
][reqtype
].width
= data
[window
][reqtype
].width
- 2*bw
89 if data
[window
][reqtype
].height
then
90 data
[window
][reqtype
].height
= math
.min(data
[window
][reqtype
].height
,
91 screen
[window
.screen
].workarea
.height
)
92 if reqtype
== "maximized_vertical" then
93 local bw
= window
.border_width
or 0
94 data
[window
][reqtype
].height
= data
[window
][reqtype
].height
- 2*bw
97 if data
[window
][reqtype
].screen
then
98 local from
= screen
[data
[window
][reqtype
].screen
].workarea
99 local to
= screen
[window
.screen
].workarea
101 if data
[window
][reqtype
].x
then
102 new_x
= to
.x
+ data
[window
][reqtype
].x
- from
.x
103 if new_x
> to
.x
+ to
.width
then new_x
= to
.x
end
104 data
[window
][reqtype
].x
= new_x
106 if data
[window
][reqtype
].y
then
107 new_y
= to
.y
+ data
[window
][reqtype
].y
- from
.y
108 if new_y
> to
.y
+ to
.width
then new_y
= to
.y
end
109 data
[window
][reqtype
].y
= new_y
117 -- Update a client's settings when its border width changes
118 local function border_change(window
)
119 -- Fix up the geometry in case this window needs to cover the whole screen.
120 local bw
= window
.border_width
or 0
121 local g
= screen
[window
.screen
].workarea
122 if window
.maximized_vertical
then
123 window
:geometry
{ height
= g
.height
- 2*bw
, y
= g
.y
}
125 if window
.maximized_horizontal
then
126 window
:geometry
{ width
= g
.width
- 2*bw
, x
= g
.x
}
128 if window
.fullscreen
then
129 -- This *will* cause an endless loop if some other property::border_width
130 -- signal dares to change the border width, too, so don't do that!
131 window
.border_width
= 0
132 window
:geometry(screen
[window
.screen
].geometry
)
137 function ewmh
.activate(c
)
138 if awesome
.startup
or c
:isvisible() then
146 -- Tag a window with its requested tag
147 function ewmh
.tag(c
, t
)
151 c
.screen
= atag
.getscreen(t
)
156 client
.connect_signal("request::activate", ewmh
.activate
)
157 client
.connect_signal("request::tag", ewmh
.tag)
158 client
.connect_signal("request::maximized_horizontal", maximized_horizontal
)
159 client
.connect_signal("request::maximized_vertical", maximized_vertical
)
160 client
.connect_signal("request::fullscreen", fullscreen
)
161 client
.connect_signal("property::screen", screen_change
)
162 client
.connect_signal("property::border_width", border_change
)
166 -- vim: filetype=lua:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80