2 * wibox.c - wibox functions
4 * Copyright © 2008 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.
29 #include "common/xcursor.h"
30 #include "common/xutil.h"
32 DO_LUA_TOSTRING(wibox_t
, wibox
, "wibox")
34 /** Take care of garbage collecting a wibox.
35 * \param L The Lua VM state.
36 * \return The number of elements pushed on stack, 0!
39 luaA_wibox_gc(lua_State
*L
)
41 wibox_t
*wibox
= luaL_checkudata(L
, 1, "wibox");
42 luaA_ref_array_wipe(&wibox
->refs
);
43 p_delete(&wibox
->cursor
);
44 simplewindow_wipe(&wibox
->sw
);
45 button_array_wipe(&wibox
->buttons
);
46 image_unref(L
, wibox
->bg_image
);
47 luaL_unref(L
, LUA_REGISTRYINDEX
, wibox
->widgets_table
);
48 luaL_unref(L
, LUA_REGISTRYINDEX
, wibox
->mouse_enter
);
49 luaL_unref(L
, LUA_REGISTRYINDEX
, wibox
->mouse_leave
);
50 widget_node_array_wipe(&wibox
->widgets
);
55 wibox_unref_simplified(wibox_t
**item
)
57 wibox_unref(globalconf
.L
, *item
);
61 wibox_need_update(wibox_t
*wibox
)
63 wibox
->need_update
= true;
64 wibox
->mouse_over
= NULL
;
68 wibox_map(wibox_t
*wibox
)
70 xcb_map_window(globalconf
.connection
, wibox
->sw
.window
);
71 /* We must make sure the wibox does not display garbage */
72 wibox_need_update(wibox
);
73 /* Stack this wibox correctly */
78 wibox_move(wibox_t
*wibox
, int16_t x
, int16_t y
)
82 simplewindow_move(&wibox
->sw
, x
, y
);
83 wibox
->screen
= screen_getbycoord(wibox
->screen
, x
, y
);
87 wibox
->sw
.geometry
.x
= x
;
88 wibox
->sw
.geometry
.y
= y
;
93 wibox_resize(wibox_t
*wibox
, uint16_t width
, uint16_t height
)
96 simplewindow_resize(&wibox
->sw
, width
, height
);
99 wibox
->sw
.geometry
.width
= width
;
100 wibox
->sw
.geometry
.height
= height
;
102 wibox_need_update(wibox
);
106 wibox_setposition(wibox_t
*wibox
, position_t p
)
108 if(p
!= wibox
->position
)
110 switch((wibox
->position
= p
))
115 simplewindow_orientation_set(&wibox
->sw
, East
);
118 simplewindow_orientation_set(&wibox
->sw
, North
);
121 simplewindow_orientation_set(&wibox
->sw
, South
);
124 /* reset width/height to 0 */
125 if(wibox
->position
!= Floating
)
126 wibox
->sw
.geometry
.width
= wibox
->sw
.geometry
.height
= 0;
128 /* recompute position */
129 wibox_position_update(wibox
);
131 /* reset all wibox position */
132 foreach(w
, wibox
->screen
->wiboxes
)
133 wibox_position_update(*w
);
135 ewmh_update_workarea(screen_virttophys(screen_array_indexof(&globalconf
.screens
, wibox
->screen
)));
137 wibox_need_update(wibox
);
141 /** Kick out systray windows.
142 * \param phys_screen Physical screen number.
145 wibox_systray_kickout(int phys_screen
)
147 xcb_screen_t
*s
= xutil_screen_get(globalconf
.connection
, phys_screen
);
149 if(globalconf
.screens
.tab
[phys_screen
].systray
.parent
!= s
->root
)
151 /* Who! Check that we're not deleting a wibox with a systray, because it
152 * may be its parent. If so, we reparent to root before, otherwise it will
154 xcb_reparent_window(globalconf
.connection
,
155 globalconf
.screens
.tab
[phys_screen
].systray
.window
,
156 s
->root
, -512, -512);
158 globalconf
.screens
.tab
[phys_screen
].systray
.parent
= s
->root
;
163 wibox_systray_refresh(wibox_t
*wibox
)
168 for(int i
= 0; i
< wibox
->widgets
.len
; i
++)
170 widget_node_t
*systray
= &wibox
->widgets
.tab
[i
];
171 if(systray
->widget
->type
== widget_systray
)
173 uint32_t config_back
[] = { wibox
->sw
.ctx
.bg
.pixel
};
174 uint32_t config_win_vals
[4];
175 uint32_t config_win_vals_off
[2] = { -512, -512 };
177 int phys_screen
= wibox
->sw
.ctx
.phys_screen
;
180 && systray
->widget
->isvisible
181 && systray
->geometry
.width
)
183 /* Set background of the systray window. */
184 xcb_change_window_attributes(globalconf
.connection
,
185 globalconf
.screens
.tab
[phys_screen
].systray
.window
,
186 XCB_CW_BACK_PIXEL
, config_back
);
188 xcb_map_window(globalconf
.connection
, globalconf
.screens
.tab
[phys_screen
].systray
.window
);
190 switch(wibox
->sw
.orientation
)
193 config_win_vals
[0] = systray
->geometry
.y
;
194 config_win_vals
[1] = wibox
->sw
.geometry
.height
- systray
->geometry
.x
- systray
->geometry
.width
;
195 config_win_vals
[2] = systray
->geometry
.height
;
196 config_win_vals
[3] = systray
->geometry
.width
;
199 config_win_vals
[0] = systray
->geometry
.y
;
200 config_win_vals
[1] = systray
->geometry
.x
;
201 config_win_vals
[2] = systray
->geometry
.height
;
202 config_win_vals
[3] = systray
->geometry
.width
;
205 config_win_vals
[0] = systray
->geometry
.x
;
206 config_win_vals
[1] = systray
->geometry
.y
;
207 config_win_vals
[2] = systray
->geometry
.width
;
208 config_win_vals
[3] = systray
->geometry
.height
;
212 if(globalconf
.screens
.tab
[phys_screen
].systray
.parent
!= wibox
->sw
.window
)
214 xcb_reparent_window(globalconf
.connection
,
215 globalconf
.screens
.tab
[phys_screen
].systray
.window
,
217 config_win_vals
[0], config_win_vals
[1]);
218 globalconf
.screens
.tab
[phys_screen
].systray
.parent
= wibox
->sw
.window
;
220 xcb_configure_window(globalconf
.connection
,
221 globalconf
.screens
.tab
[phys_screen
].systray
.window
,
223 | XCB_CONFIG_WINDOW_Y
224 | XCB_CONFIG_WINDOW_WIDTH
225 | XCB_CONFIG_WINDOW_HEIGHT
,
227 /* width = height = systray height */
228 config_win_vals
[2] = config_win_vals
[3] = systray
->geometry
.height
;
229 config_win_vals
[0] = 0;
232 return wibox_systray_kickout(phys_screen
);
234 switch(wibox
->sw
.orientation
)
237 config_win_vals
[1] = systray
->geometry
.width
- config_win_vals
[3];
238 for(int j
= 0; j
< globalconf
.embedded
.len
; j
++)
240 em
= &globalconf
.embedded
.tab
[j
];
241 if(em
->phys_screen
== phys_screen
)
243 if(config_win_vals
[1] - config_win_vals
[2] >= (uint32_t) wibox
->sw
.geometry
.y
)
245 xcb_map_window(globalconf
.connection
, em
->win
);
246 xcb_configure_window(globalconf
.connection
, em
->win
,
248 | XCB_CONFIG_WINDOW_Y
249 | XCB_CONFIG_WINDOW_WIDTH
250 | XCB_CONFIG_WINDOW_HEIGHT
,
252 config_win_vals
[1] -= config_win_vals
[3];
255 xcb_configure_window(globalconf
.connection
, em
->win
,
257 | XCB_CONFIG_WINDOW_Y
,
258 config_win_vals_off
);
263 config_win_vals
[1] = 0;
264 for(int j
= 0; j
< globalconf
.embedded
.len
; j
++)
266 em
= &globalconf
.embedded
.tab
[j
];
267 if(em
->phys_screen
== phys_screen
)
269 /* if(y + width <= wibox.y + systray.right) */
270 if(config_win_vals
[1] + config_win_vals
[3] <= (uint32_t) wibox
->sw
.geometry
.y
+ AREA_RIGHT(systray
->geometry
))
272 xcb_map_window(globalconf
.connection
, em
->win
);
273 xcb_configure_window(globalconf
.connection
, em
->win
,
275 | XCB_CONFIG_WINDOW_Y
276 | XCB_CONFIG_WINDOW_WIDTH
277 | XCB_CONFIG_WINDOW_HEIGHT
,
279 config_win_vals
[1] += config_win_vals
[3];
282 xcb_configure_window(globalconf
.connection
, em
->win
,
284 | XCB_CONFIG_WINDOW_Y
,
285 config_win_vals_off
);
290 config_win_vals
[1] = 0;
291 for(int j
= 0; j
< globalconf
.embedded
.len
; j
++)
293 em
= &globalconf
.embedded
.tab
[j
];
294 if(em
->phys_screen
== phys_screen
)
296 /* if(x + width < systray.x + systray.width) */
297 if(config_win_vals
[0] + config_win_vals
[2] <= (uint32_t) AREA_RIGHT(systray
->geometry
) + wibox
->sw
.geometry
.x
)
299 xcb_map_window(globalconf
.connection
, em
->win
);
300 xcb_configure_window(globalconf
.connection
, em
->win
,
302 | XCB_CONFIG_WINDOW_Y
303 | XCB_CONFIG_WINDOW_WIDTH
304 | XCB_CONFIG_WINDOW_HEIGHT
,
306 config_win_vals
[0] += config_win_vals
[2];
309 xcb_configure_window(globalconf
.connection
, em
->win
,
311 | XCB_CONFIG_WINDOW_Y
,
312 config_win_vals_off
);
322 /* Only called by wibox_position_update() */
324 wibox_position_update_floating(wibox_t
*wibox
)
326 area_t wingeom
= wibox
->sw
.geometry
;
328 /* We only make sure the wibox is at least 1x1 pixel big. */
329 wingeom
.width
= MAX(1, wibox
->sw
.geometry
.width
);
330 wingeom
.height
= MAX(1, wibox
->sw
.geometry
.height
);
332 if(wingeom
.width
!= wibox
->sw
.geometry
.width
333 || wingeom
.height
!= wibox
->sw
.geometry
.height
)
334 wibox_resize(wibox
, wingeom
.width
, wingeom
.height
);
337 /* Only called by wibox_position_update() */
339 wibox_position_update_non_floating(wibox_t
*wibox
)
341 area_t area
, wingeom
= wibox
->sw
.geometry
;
344 /* Everything we do below needs the wibox' screen.
345 * No screen, nothing to do.
350 /* This wibox limits the space available to clients and thus clients
351 * need to be repositioned.
353 wibox
->screen
->need_arrange
= true;
355 /* Place wibox'es at the edge of the screen, struts come later. */
356 area
= screen_area_get(wibox
->screen
, NULL
,
357 &wibox
->screen
->padding
, false);
359 /* Top and Bottom wibox_t have prio */
360 foreach(_w
, wibox
->screen
->wiboxes
)
363 /* Ignore every wibox after me that is in the same position */
369 else if((ignore
&& wibox
->position
== w
->position
) || !w
->isvisible
)
376 if(wibox
->position
== Left
)
377 area
.x
+= wibox
->sw
.geometry
.width
;
380 if(wibox
->position
== Right
)
381 area
.x
-= wibox
->sw
.geometry
.width
;
384 switch(wibox
->position
)
387 area
.y
+= w
->sw
.geometry
.height
;
391 area
.height
-= w
->sw
.geometry
.height
;
392 area
.y
+= w
->sw
.geometry
.height
;
399 switch(wibox
->position
)
402 area
.y
-= w
->sw
.geometry
.height
;
406 area
.height
-= w
->sw
.geometry
.height
;
415 /* The "length" of a wibox is always chosen to be the optimal size (non-floating).
416 * The "width" of a wibox is kept if it exists.
418 switch(wibox
->position
)
421 wingeom
.height
= area
.height
- 2 * wibox
->sw
.border
.width
;
422 wingeom
.width
= wibox
->sw
.geometry
.width
> 0 ? wibox
->sw
.geometry
.width
: 1.5 * globalconf
.font
->height
;
423 wingeom
.x
= area
.x
+ area
.width
- wingeom
.width
;
430 wingeom
.y
= area
.y
+ area
.height
- wingeom
.height
;
433 wingeom
.y
= (area
.y
+ area
.height
- wingeom
.height
) / 2;
438 wingeom
.height
= area
.height
- 2 * wibox
->sw
.border
.width
;
439 wingeom
.width
= wibox
->sw
.geometry
.width
> 0 ? wibox
->sw
.geometry
.width
: 1.5 * globalconf
.font
->height
;
444 wingeom
.y
= (area
.y
+ area
.height
) - wingeom
.height
;
450 wingeom
.y
= (area
.y
+ area
.height
- wingeom
.height
) / 2;
454 wingeom
.height
= wibox
->sw
.geometry
.height
> 0 ? wibox
->sw
.geometry
.height
: 1.5 * globalconf
.font
->height
;
455 wingeom
.width
= area
.width
- 2 * wibox
->sw
.border
.width
;
456 wingeom
.y
= (area
.y
+ area
.height
) - wingeom
.height
;
463 wingeom
.x
+= area
.width
- wingeom
.width
;
466 wingeom
.x
+= (area
.width
- wingeom
.width
) / 2;
471 wingeom
.height
= wibox
->sw
.geometry
.height
> 0 ? wibox
->sw
.geometry
.height
: 1.5 * globalconf
.font
->height
;
472 wingeom
.width
= area
.width
- 2 * wibox
->sw
.border
.width
;
480 wingeom
.x
+= area
.width
- wingeom
.width
;
483 wingeom
.x
+= (area
.width
- wingeom
.width
) / 2;
488 /* Floating wiboxes are not handled here, but in
489 * wibox_position_update_floating(), but the compiler insists...
494 /* same window size and position ? */
495 if(wingeom
.width
!= wibox
->sw
.geometry
.width
496 || wingeom
.height
!= wibox
->sw
.geometry
.height
)
497 wibox_resize(wibox
, wingeom
.width
, wingeom
.height
);
499 if(wingeom
.x
!= wibox
->sw
.geometry
.x
500 || wingeom
.y
!= wibox
->sw
.geometry
.y
)
501 wibox_move(wibox
, wingeom
.x
, wingeom
.y
);
504 /** Update the wibox position. It deletes every wibox resources and
506 * \param wibox The wibox.
509 wibox_position_update(wibox_t
*wibox
)
511 if(wibox
->position
== Floating
)
512 wibox_position_update_floating(wibox
);
514 wibox_position_update_non_floating(wibox
);
517 /** Get a wibox by its window.
518 * \param w The window id.
519 * \return A wibox if found, NULL otherwise.
522 wibox_getbywin(xcb_window_t win
)
524 foreach(screen
, globalconf
.screens
)
525 foreach(w
, screen
->wiboxes
)
526 if((*w
)->sw
.window
== win
)
529 foreach(_c
, globalconf
.clients
)
532 if(c
->titlebar
&& c
->titlebar
->sw
.window
== win
)
540 * \param wibox The wibox to draw.
543 wibox_draw(wibox_t
*wibox
)
547 widget_render(wibox
);
548 simplewindow_refresh_pixmap(&wibox
->sw
);
550 wibox
->need_update
= false;
553 wibox_systray_refresh(wibox
);
556 /** Refresh all wiboxes.
561 foreach(screen
, globalconf
.screens
)
562 foreach(w
, screen
->wiboxes
)
563 if((*w
)->need_update
)
566 foreach(_c
, globalconf
.clients
)
569 if(c
->titlebar
&& c
->titlebar
->need_update
)
570 wibox_draw(c
->titlebar
);
574 /** Reposition all wiboxes.
577 wibox_update_positions(void)
579 foreach(screen
, globalconf
.screens
)
580 foreach(w
, screen
->wiboxes
)
581 wibox_position_update(*w
);
584 /** Set a wibox visible or not.
585 * \param wibox The wibox.
586 * \param v The visible value.
589 wibox_setvisible(wibox_t
*wibox
, bool v
)
591 if(v
!= wibox
->isvisible
)
593 wibox
->isvisible
= v
;
594 wibox
->mouse_over
= NULL
;
596 if(wibox
->screen
!= NULL
)
601 xcb_unmap_window(globalconf
.connection
, wibox
->sw
.window
);
603 /* kick out systray if needed */
604 wibox_systray_refresh(wibox
);
606 /* All the other wibox and ourselves need to be repositioned */
607 foreach(w
, wibox
->screen
->wiboxes
)
608 wibox_position_update(*w
);
613 /** Remove a wibox from a screen.
614 * \param wibox Wibox to detach from screen.
617 wibox_detach(wibox_t
*wibox
)
619 if(wibox
->screen
!= NULL
)
623 /* save visible state */
624 v
= wibox
->isvisible
;
625 wibox
->isvisible
= false;
626 wibox_systray_refresh(wibox
);
627 wibox_position_update(wibox
);
628 /* restore position */
629 wibox
->isvisible
= v
;
631 wibox
->mouse_over
= NULL
;
633 simplewindow_wipe(&wibox
->sw
);
635 wibox
->screen
->need_arrange
= true;
637 foreach(item
, wibox
->screen
->wiboxes
)
640 wibox_array_remove(&wibox
->screen
->wiboxes
, item
);
644 wibox
->screen
= NULL
;
645 wibox_unref(globalconf
.L
, wibox
);
649 /** Attach a wibox that is on top of the stack.
650 * \param s The screen to attach the wibox to.
653 wibox_attach(screen_t
*s
)
655 int phys_screen
= screen_virttophys(screen_array_indexof(&globalconf
.screens
, s
));
657 wibox_t
*wibox
= wibox_ref(globalconf
.L
);
661 /* Set the wibox screen */
664 /* Check that the wibox coordinates matches the screen. */
666 screen_getbycoord(wibox
->screen
, wibox
->sw
.geometry
.x
, wibox
->sw
.geometry
.y
);
668 /* If it does not match, move it to the screen coordinates */
669 if(cscreen
!= wibox
->screen
)
670 wibox_move(wibox
, s
->geometry
.x
, s
->geometry
.y
);
672 wibox_array_append(&s
->wiboxes
, wibox
);
674 /* compute x/y/width/height if not set */
675 wibox_position_update(wibox
);
677 simplewindow_init(&wibox
->sw
, phys_screen
,
679 wibox
->sw
.border
.width
,
680 wibox
->sw
.orientation
,
681 &wibox
->sw
.ctx
.fg
, &wibox
->sw
.ctx
.bg
);
683 simplewindow_border_color_set(&wibox
->sw
, &wibox
->sw
.border
.color
);
685 simplewindow_cursor_set(&wibox
->sw
,
686 xcursor_new(globalconf
.connection
, xcursor_font_fromstr(wibox
->cursor
)));
688 /* All the other wibox and ourselves need to be repositioned */
689 foreach(w
, s
->wiboxes
)
690 wibox_position_update(*w
);
692 ewmh_update_workarea(phys_screen
);
697 wibox_need_update(wibox
);
700 /** Create a new wibox.
701 * \param L The Lua VM state.
704 * \lparam A table with optionaly defined values:
705 * position, align, fg, bg, border_width, border_color, ontop, width and height.
706 * \lreturn A brand new wibox.
709 luaA_wibox_new(lua_State
*L
)
714 xcolor_init_request_t reqs
[3];
715 int i
, reqs_nbr
= -1;
717 luaA_checktable(L
, 2);
720 w
->widgets_table
= LUA_REFNIL
;
722 w
->sw
.ctx
.fg
= globalconf
.colors
.fg
;
723 if((buf
= luaA_getopt_lstring(L
, 2, "fg", NULL
, &len
)))
724 reqs
[++reqs_nbr
] = xcolor_init_unchecked(&w
->sw
.ctx
.fg
, buf
, len
);
726 w
->sw
.ctx
.bg
= globalconf
.colors
.bg
;
727 if((buf
= luaA_getopt_lstring(L
, 2, "bg", NULL
, &len
)))
728 reqs
[++reqs_nbr
] = xcolor_init_unchecked(&w
->sw
.ctx
.bg
, buf
, len
);
730 w
->sw
.border
.color
= globalconf
.colors
.bg
;
731 if((buf
= luaA_getopt_lstring(L
, 2, "border_color", NULL
, &len
)))
732 reqs
[++reqs_nbr
] = xcolor_init_unchecked(&w
->sw
.border
.color
, buf
, len
);
734 w
->ontop
= luaA_getopt_boolean(L
, 2, "ontop", false);
736 buf
= luaA_getopt_lstring(L
, 2, "align", "left", &len
);
737 w
->align
= draw_align_fromstr(buf
, len
);
739 w
->sw
.border
.width
= luaA_getopt_number(L
, 2, "border_width", 0);
741 buf
= luaA_getopt_lstring(L
, 2, "position", "top", &len
);
743 switch((w
->position
= position_fromstr(buf
, len
)))
748 w
->sw
.orientation
= East
;
751 w
->sw
.orientation
= North
;
754 w
->sw
.orientation
= South
;
758 w
->sw
.geometry
.x
= luaA_getopt_number(L
, 2, "x", 0);
759 w
->sw
.geometry
.y
= luaA_getopt_number(L
, 2, "y", 0);
760 w
->sw
.geometry
.width
= luaA_getopt_number(L
, 2, "width", 0);
761 w
->sw
.geometry
.height
= luaA_getopt_number(L
, 2, "height", 0);
764 w
->cursor
= a_strdup("left_ptr");
766 w
->mouse_enter
= w
->mouse_leave
= LUA_REFNIL
;
768 for(i
= 0; i
<= reqs_nbr
; i
++)
769 xcolor_init_reply(reqs
[i
]);
774 /** Rebuild wibox widgets list.
775 * \param L The Lua VM state.
776 * \param wibox The wibox.
779 wibox_widgets_table_build(lua_State
*L
, wibox_t
*wibox
)
781 widget_node_array_wipe(&wibox
->widgets
);
782 widget_node_array_init(&wibox
->widgets
);
783 luaA_table2widgets(L
, &wibox
->widgets
);
784 wibox_need_update(wibox
);
787 /** Check if a wibox widget table has an item.
788 * \param L The Lua VM state.
789 * \param wibox The wibox.
790 * \param item The item to look for.
793 luaA_wibox_hasitem(lua_State
*L
, wibox_t
*wibox
, const void *item
)
795 if(wibox
->widgets_table
!= LUA_REFNIL
)
797 lua_rawgeti(globalconf
.L
, LUA_REGISTRYINDEX
, wibox
->widgets_table
);
798 if(lua_topointer(L
, -1) == item
|| luaA_hasitem(L
, item
))
804 /** Invalidate a wibox by a Lua object (table, etc).
805 * \param L The Lua VM state.
806 * \param item The object identifier.
809 luaA_wibox_invalidate_byitem(lua_State
*L
, const void *item
)
811 foreach(screen
, globalconf
.screens
)
812 foreach(w
, screen
->wiboxes
)
815 if(luaA_wibox_hasitem(L
, wibox
, item
))
817 /* recompute widget node list */
818 wibox_widgets_table_build(L
, wibox
);
819 lua_pop(L
, 1); /* remove widgets table */
824 foreach(_c
, globalconf
.clients
)
827 if(c
->titlebar
&& luaA_wibox_hasitem(L
, c
->titlebar
, item
))
829 /* recompute widget node list */
830 wibox_widgets_table_build(L
, c
->titlebar
);
831 lua_pop(L
, 1); /* remove widgets table */
837 * \param L The Lua VM state.
838 * \return The number of elements pushed on stack.
840 * \lfield screen Screen number.
841 * \lfield client The client attached to (titlebar).
842 * \lfield border_width Border width.
843 * \lfield border_color Border color.
844 * \lfield align The alignment.
845 * \lfield fg Foreground color.
846 * \lfield bg Background color.
847 * \lfield bg_image Background image.
848 * \lfield position The position.
849 * \lfield ontop On top of other windows.
850 * \lfield cursor The mouse cursor.
851 * \lfield visible Visibility.
852 * \lfield orientation The drawing orientation: east, north or south.
853 * \lfield widgets An array with all widgets drawn on this wibox.
854 * \lfield opacity The opacity of the wibox, between 0 and 1.
855 * \lfield mouse_enter A function to execute when the mouse enter the widget.
856 * \lfield mouse_leave A function to execute when the mouse leave the widget.
859 luaA_wibox_index(lua_State
*L
)
862 wibox_t
*wibox
= luaL_checkudata(L
, 1, "wibox");
863 const char *attr
= luaL_checklstring(L
, 2, &len
);
865 if(luaA_usemetatable(L
, 1, 2))
868 switch(a_tokenize(attr
, len
))
871 lua_pushboolean(L
, wibox
->isvisible
);
874 return client_push(L
, client_getbytitlebar(wibox
));
878 lua_pushnumber(L
, screen_array_indexof(&globalconf
.screens
, wibox
->screen
) + 1);
880 case A_TK_BORDER_WIDTH
:
881 lua_pushnumber(L
, wibox
->sw
.border
.width
);
883 case A_TK_BORDER_COLOR
:
884 luaA_pushxcolor(L
, &wibox
->sw
.border
.color
);
887 lua_pushstring(L
, draw_align_tostr(wibox
->align
));
890 luaA_pushxcolor(L
, &wibox
->sw
.ctx
.fg
);
893 luaA_pushxcolor(L
, &wibox
->sw
.ctx
.bg
);
896 image_push(L
, wibox
->bg_image
);
899 lua_pushstring(L
, position_tostr(wibox
->position
));
902 lua_pushboolean(L
, wibox
->ontop
);
904 case A_TK_ORIENTATION
:
905 lua_pushstring(L
, orientation_tostr(wibox
->sw
.orientation
));
908 if(wibox
->widgets_table
!= LUA_REFNIL
)
909 lua_rawgeti(L
, LUA_REGISTRYINDEX
, wibox
->widgets_table
);
914 lua_pushstring(L
, wibox
->cursor
);
919 if ((d
= window_opacity_get(wibox
->sw
.window
)) >= 0)
920 lua_pushnumber(L
, d
);
925 case A_TK_MOUSE_ENTER
:
926 if(wibox
->mouse_enter
!= LUA_REFNIL
)
927 lua_rawgeti(L
, LUA_REGISTRYINDEX
, wibox
->mouse_enter
);
931 case A_TK_MOUSE_LEAVE
:
932 if(wibox
->mouse_leave
!= LUA_REFNIL
)
933 lua_rawgeti(L
, LUA_REGISTRYINDEX
, wibox
->mouse_leave
);
944 /* Set or get the wibox geometry.
945 * \param L The Lua VM state.
946 * \return The number of elements pushed on stack.
948 * \lparam An optional table with wibox geometry.
949 * \lreturn The wibox geometry.
952 luaA_wibox_geometry(lua_State
*L
)
954 wibox_t
*wibox
= luaL_checkudata(L
, 1, "wibox");
956 if(lua_gettop(L
) == 2)
960 luaA_checktable(L
, 2);
961 wingeom
.x
= luaA_getopt_number(L
, 2, "x", wibox
->sw
.geometry
.x
);
962 wingeom
.y
= luaA_getopt_number(L
, 2, "y", wibox
->sw
.geometry
.y
);
963 wingeom
.width
= luaA_getopt_number(L
, 2, "width", wibox
->sw
.geometry
.width
);
964 wingeom
.height
= luaA_getopt_number(L
, 2, "height", wibox
->sw
.geometry
.height
);
968 case WIBOX_TYPE_TITLEBAR
:
969 wibox_resize(wibox
, wingeom
.width
, wingeom
.height
);
971 case WIBOX_TYPE_NORMAL
:
972 if(wibox
->position
== Floating
)
973 wibox_moveresize(wibox
, wingeom
);
974 else if(wingeom
.width
!= wibox
->sw
.geometry
.width
975 || wingeom
.height
!= wibox
->sw
.geometry
.height
)
977 wibox_resize(wibox
, wingeom
.width
, wingeom
.height
);
978 wibox
->screen
->need_arrange
= true;
984 return luaA_pusharea(L
, wibox
->sw
.geometry
);
988 * \param L The Lua VM state.
989 * \return The number of elements pushed on stack.
992 luaA_wibox_newindex(lua_State
*L
)
995 wibox_t
*wibox
= luaL_checkudata(L
, 1, "wibox");
996 const char *buf
, *attr
= luaL_checklstring(L
, 2, &len
);
999 switch((tok
= a_tokenize(attr
, len
)))
1004 if((buf
= luaL_checklstring(L
, 3, &len
)))
1005 if(xcolor_init_reply(xcolor_init_unchecked(&wibox
->sw
.ctx
.fg
, buf
, len
)))
1006 wibox
->need_update
= true;
1009 if((buf
= luaL_checklstring(L
, 3, &len
)))
1010 if(xcolor_init_reply(xcolor_init_unchecked(&wibox
->sw
.ctx
.bg
, buf
, len
)))
1011 wibox
->need_update
= true;
1014 image_unref(L
, wibox
->bg_image
);
1015 wibox
->bg_image
= image_ref(L
);
1016 wibox
->need_update
= true;
1019 buf
= luaL_checklstring(L
, 3, &len
);
1020 wibox
->align
= draw_align_fromstr(buf
, len
);
1023 case WIBOX_TYPE_NORMAL
:
1024 wibox_position_update(wibox
);
1026 case WIBOX_TYPE_TITLEBAR
:
1027 titlebar_update_geometry(client_getbytitlebar(wibox
));
1034 case WIBOX_TYPE_TITLEBAR
:
1035 return luaA_titlebar_newindex(L
, wibox
, tok
);
1036 case WIBOX_TYPE_NORMAL
:
1037 if((buf
= luaL_checklstring(L
, 3, &len
)))
1038 wibox_setposition(wibox
, position_fromstr(buf
, len
));
1045 titlebar_client_detach(client_getbytitlebar(wibox
));
1048 client_t
*c
= luaA_client_checkudata(L
, -1);
1049 lua_pushvalue(L
, 1);
1050 titlebar_client_attach(c
);
1054 if((buf
= luaL_checkstring(L
, 3)))
1056 uint16_t cursor_font
= xcursor_font_fromstr(buf
);
1059 xcb_cursor_t cursor
= xcursor_new(globalconf
.connection
, cursor_font
);
1060 p_delete(&wibox
->cursor
);
1061 wibox
->cursor
= a_strdup(buf
);
1062 simplewindow_cursor_set(&wibox
->sw
, cursor
);
1069 wibox_detach(wibox
);
1070 titlebar_client_detach(client_getbytitlebar(wibox
));
1074 int screen
= luaL_checknumber(L
, 3) - 1;
1075 luaA_checkscreen(screen
);
1076 if(!wibox
->screen
|| screen
!= screen_array_indexof(&globalconf
.screens
, wibox
->screen
))
1078 titlebar_client_detach(client_getbytitlebar(wibox
));
1079 lua_pushvalue(L
, 1);
1080 wibox_attach(&globalconf
.screens
.tab
[screen
]);
1085 b
= luaA_checkboolean(L
, 3);
1086 if(b
!= wibox
->ontop
)
1092 case A_TK_ORIENTATION
:
1093 if((buf
= luaL_checklstring(L
, 3, &len
)))
1095 simplewindow_orientation_set(&wibox
->sw
, orientation_fromstr(buf
, len
));
1096 wibox_need_update(wibox
);
1099 case A_TK_BORDER_COLOR
:
1100 if((buf
= luaL_checklstring(L
, 3, &len
)))
1101 if(xcolor_init_reply(xcolor_init_unchecked(&wibox
->sw
.border
.color
, buf
, len
)))
1102 if(wibox
->sw
.window
)
1103 simplewindow_border_color_set(&wibox
->sw
, &wibox
->sw
.border
.color
);
1106 b
= luaA_checkboolean(L
, 3);
1107 if(b
!= wibox
->isvisible
)
1110 case WIBOX_TYPE_NORMAL
:
1111 wibox_setvisible(wibox
, b
);
1113 case WIBOX_TYPE_TITLEBAR
:
1114 titlebar_set_visible(wibox
, b
);
1119 if(luaA_isloop(L
, 3))
1121 luaA_warn(L
, "table is looping, cannot use this as widget table");
1124 /* register object */
1125 luaA_register(L
, 3, &wibox
->widgets_table
);
1126 /* duplicate table because next function will eat it */
1127 lua_pushvalue(L
, -1);
1128 /* recompute widget node list */
1129 wibox_widgets_table_build(L
, wibox
);
1130 luaA_table2wtable(L
);
1134 window_opacity_set(wibox
->sw
.window
, -1);
1137 double d
= luaL_checknumber(L
, 3);
1138 if(d
>= 0 && d
<= 1)
1139 window_opacity_set(wibox
->sw
.window
, d
);
1142 case A_TK_MOUSE_ENTER
:
1143 luaA_registerfct(L
, 3, &wibox
->mouse_enter
);
1145 case A_TK_MOUSE_LEAVE
:
1146 luaA_registerfct(L
, 3, &wibox
->mouse_leave
);
1151 case WIBOX_TYPE_TITLEBAR
:
1152 return luaA_titlebar_newindex(L
, wibox
, tok
);
1153 case WIBOX_TYPE_NORMAL
:
1161 /** Get or set mouse buttons bindings to a wibox.
1162 * \param L The Lua VM state.
1165 * \lparam An array of mouse button bindings objects, or nothing.
1166 * \return The array of mouse button bindings objects of this wibox.
1169 luaA_wibox_buttons(lua_State
*L
)
1171 wibox_t
*wibox
= luaL_checkudata(L
, 1, "wibox");
1172 button_array_t
*buttons
= &wibox
->buttons
;
1174 if(lua_gettop(L
) == 2)
1176 luaA_button_array_set(L
, 2, buttons
);
1180 return luaA_button_array_get(L
, buttons
);
1183 const struct luaL_reg awesome_wibox_methods
[] =
1185 { "__call", luaA_wibox_new
},
1188 const struct luaL_reg awesome_wibox_meta
[] =
1190 { "buttons", luaA_wibox_buttons
},
1191 { "geometry", luaA_wibox_geometry
},
1192 { "__index", luaA_wibox_index
},
1193 { "__newindex", luaA_wibox_newindex
},
1194 { "__gc", luaA_wibox_gc
},
1195 { "__tostring", luaA_wibox_tostring
},
1199 // vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80