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.
27 #include "common/xcursor.h"
29 extern awesome_t globalconf
;
31 DO_LUA_NEW(extern, wibox_t
, wibox
, "wibox", wibox_ref
)
32 DO_LUA_GC(wibox_t
, wibox
, "wibox", wibox_unref
)
33 DO_LUA_EQ(wibox_t
, wibox
, "wibox")
36 wibox_move(wibox_t
*wibox
, int16_t x
, int16_t y
)
39 simplewindow_move(&wibox
->sw
, x
, y
);
42 wibox
->sw
.geometry
.x
= x
;
43 wibox
->sw
.geometry
.y
= y
;
48 wibox_resize(wibox_t
*wibox
, uint16_t width
, uint16_t height
)
51 simplewindow_resize(&wibox
->sw
, width
, height
);
54 wibox
->sw
.geometry
.width
= width
;
55 wibox
->sw
.geometry
.height
= height
;
57 wibox
->need_update
= true;
61 wibox_setposition(wibox_t
*wibox
, position_t p
)
63 if(p
!= wibox
->position
)
65 switch((wibox
->position
= p
))
70 simplewindow_orientation_set(&wibox
->sw
, East
);
73 simplewindow_orientation_set(&wibox
->sw
, North
);
76 simplewindow_orientation_set(&wibox
->sw
, South
);
79 /* reset width/height to 0 */
80 if(wibox
->position
!= Floating
)
81 wibox
->sw
.geometry
.width
= wibox
->sw
.geometry
.height
= 0;
83 /* recompute position */
84 wibox_position_update(wibox
);
86 /* reset all wibox position */
87 wibox_array_t
*w
= &globalconf
.screens
[wibox
->screen
].wiboxes
;
88 for(int i
= 0; i
< w
->len
; i
++)
89 wibox_position_update(w
->tab
[i
]);
91 ewmh_update_workarea(screen_virttophys(wibox
->screen
));
93 wibox
->need_update
= true;
97 /** Kick out systray windows.
98 * \param phys_screen Physical screen number.
101 wibox_systray_kickout(int phys_screen
)
103 xcb_screen_t
*s
= xutil_screen_get(globalconf
.connection
, phys_screen
);
105 /* Who! Check that we're not deleting a wibox with a systray, because it
106 * may be its parent. If so, we reparent to root before, otherwise it will
108 xcb_reparent_window(globalconf
.connection
,
109 globalconf
.screens
[phys_screen
].systray
.window
,
110 s
->root
, -512, -512);
112 globalconf
.screens
[phys_screen
].systray
.parent
= s
->root
;
116 wibox_systray_refresh(wibox_t
*wibox
)
118 if(wibox
->screen
== SCREEN_UNDEF
)
121 for(int i
= 0; i
< wibox
->widgets
.len
; i
++)
123 widget_node_t
*systray
= &wibox
->widgets
.tab
[i
];
124 if(systray
->widget
->type
== widget_systray
)
126 uint32_t config_back
[] = { wibox
->sw
.ctx
.bg
.pixel
};
127 uint32_t config_win_vals
[4];
128 uint32_t config_win_vals_off
[2] = { -512, -512 };
131 int phys_screen
= wibox
->sw
.ctx
.phys_screen
;
134 && systray
->widget
->isvisible
135 && systray
->geometry
.width
)
137 pos
= wibox
->position
;
139 /* Set background of the systray window. */
140 xcb_change_window_attributes(globalconf
.connection
,
141 globalconf
.screens
[phys_screen
].systray
.window
,
142 XCB_CW_BACK_PIXEL
, config_back
);
144 xcb_map_window(globalconf
.connection
, globalconf
.screens
[phys_screen
].systray
.window
);
146 switch(wibox
->position
)
149 config_win_vals
[0] = systray
->geometry
.y
;
150 config_win_vals
[1] = wibox
->sw
.geometry
.height
- systray
->geometry
.x
- systray
->geometry
.width
;
151 config_win_vals
[2] = systray
->geometry
.height
;
152 config_win_vals
[3] = systray
->geometry
.width
;
155 config_win_vals
[0] = systray
->geometry
.y
;
156 config_win_vals
[1] = systray
->geometry
.x
;
157 config_win_vals
[2] = systray
->geometry
.height
;
158 config_win_vals
[3] = systray
->geometry
.width
;
161 config_win_vals
[0] = systray
->geometry
.x
;
162 config_win_vals
[1] = systray
->geometry
.y
;
163 config_win_vals
[2] = systray
->geometry
.width
;
164 config_win_vals
[3] = systray
->geometry
.height
;
168 if(globalconf
.screens
[phys_screen
].systray
.parent
!= wibox
->sw
.window
)
170 xcb_reparent_window(globalconf
.connection
,
171 globalconf
.screens
[phys_screen
].systray
.window
,
173 config_win_vals
[0], config_win_vals
[1]);
174 globalconf
.screens
[phys_screen
].systray
.parent
= wibox
->sw
.window
;
176 xcb_configure_window(globalconf
.connection
,
177 globalconf
.screens
[phys_screen
].systray
.window
,
179 | XCB_CONFIG_WINDOW_Y
180 | XCB_CONFIG_WINDOW_WIDTH
181 | XCB_CONFIG_WINDOW_HEIGHT
,
183 /* width = height = systray height */
184 config_win_vals
[2] = config_win_vals
[3] = systray
->geometry
.height
;
185 config_win_vals
[0] = 0;
188 return wibox_systray_kickout(phys_screen
);
193 config_win_vals
[1] = systray
->geometry
.width
- config_win_vals
[3];
194 for(int j
= 0; j
< globalconf
.embedded
.len
; j
++)
196 em
= &globalconf
.embedded
.tab
[j
];
197 if(em
->phys_screen
== phys_screen
)
199 if(config_win_vals
[1] - config_win_vals
[2] >= (uint32_t) wibox
->sw
.geometry
.y
)
201 xcb_map_window(globalconf
.connection
, em
->win
);
202 xcb_configure_window(globalconf
.connection
, em
->win
,
204 | XCB_CONFIG_WINDOW_Y
205 | XCB_CONFIG_WINDOW_WIDTH
206 | XCB_CONFIG_WINDOW_HEIGHT
,
208 config_win_vals
[1] -= config_win_vals
[3];
211 xcb_configure_window(globalconf
.connection
, em
->win
,
213 | XCB_CONFIG_WINDOW_Y
,
214 config_win_vals_off
);
219 config_win_vals
[1] = 0;
220 for(int j
= 0; j
< globalconf
.embedded
.len
; j
++)
222 em
= &globalconf
.embedded
.tab
[j
];
223 if(em
->phys_screen
== phys_screen
)
225 if(config_win_vals
[1] + config_win_vals
[3] <= (uint32_t) wibox
->sw
.geometry
.y
+ wibox
->sw
.geometry
.width
)
227 xcb_map_window(globalconf
.connection
, em
->win
);
228 xcb_configure_window(globalconf
.connection
, em
->win
,
230 | XCB_CONFIG_WINDOW_Y
231 | XCB_CONFIG_WINDOW_WIDTH
232 | XCB_CONFIG_WINDOW_HEIGHT
,
234 config_win_vals
[1] += config_win_vals
[3];
237 xcb_configure_window(globalconf
.connection
, em
->win
,
239 | XCB_CONFIG_WINDOW_Y
,
240 config_win_vals_off
);
247 config_win_vals
[1] = 0;
248 for(int j
= 0; j
< globalconf
.embedded
.len
; j
++)
250 em
= &globalconf
.embedded
.tab
[j
];
251 if(em
->phys_screen
== phys_screen
)
253 /* if(x + width < systray.x + systray.width) */
254 if(config_win_vals
[0] + config_win_vals
[2] <= (uint32_t) AREA_RIGHT(systray
->geometry
) + wibox
->sw
.geometry
.x
)
256 xcb_map_window(globalconf
.connection
, em
->win
);
257 xcb_configure_window(globalconf
.connection
, em
->win
,
259 | XCB_CONFIG_WINDOW_Y
260 | XCB_CONFIG_WINDOW_WIDTH
261 | XCB_CONFIG_WINDOW_HEIGHT
,
263 config_win_vals
[0] += config_win_vals
[2];
266 xcb_configure_window(globalconf
.connection
, em
->win
,
268 | XCB_CONFIG_WINDOW_Y
,
269 config_win_vals_off
);
279 /** Update the wibox position. It deletes every wibox resources and
281 * \param wibox The wibox.
284 wibox_position_update(wibox_t
*wibox
)
286 area_t area
, wingeom
= wibox
->sw
.geometry
;
289 globalconf
.screens
[wibox
->screen
].need_arrange
= true;
291 area
= screen_area_get(wibox
->screen
, NULL
,
292 &globalconf
.screens
[wibox
->screen
].padding
, true);
294 /* Top and Bottom wibox_t have prio */
295 if(wibox
->position
!= Floating
)
296 for(int i
= 0; i
< globalconf
.screens
[wibox
->screen
].wiboxes
.len
; i
++)
298 wibox_t
*w
= globalconf
.screens
[wibox
->screen
].wiboxes
.tab
[i
];
299 /* Ignore every wibox after me that is in the same position */
305 else if((ignore
&& wibox
->position
== w
->position
) || !w
->isvisible
)
312 switch(wibox
->position
)
315 area
.x
+= wibox
->sw
.geometry
.height
;
322 switch(wibox
->position
)
325 area
.x
-= wibox
->sw
.geometry
.height
;
332 switch(wibox
->position
)
335 area
.y
+= w
->sw
.geometry
.height
;
339 area
.height
-= w
->sw
.geometry
.height
;
340 area
.y
+= w
->sw
.geometry
.height
;
347 switch(wibox
->position
)
350 area
.y
-= w
->sw
.geometry
.height
;
354 area
.height
-= w
->sw
.geometry
.height
;
363 /* The "length" of a wibox is always chosen to be the optimal size (non-floating).
364 * The "width" of a wibox is kept if it exists.
366 switch(wibox
->position
)
369 wingeom
.height
= area
.height
;
370 wingeom
.width
= wibox
->sw
.geometry
.width
> 0 ? wibox
->sw
.geometry
.width
: 1.5 * globalconf
.font
->height
;
371 wingeom
.x
= area
.x
+ area
.width
- wingeom
.width
;
378 wingeom
.y
= area
.y
+ area
.height
- wingeom
.height
;
381 wingeom
.y
= (area
.y
+ area
.height
- wingeom
.height
) / 2;
386 wingeom
.height
= area
.height
;
387 wingeom
.width
= wibox
->sw
.geometry
.width
> 0 ? wibox
->sw
.geometry
.width
: 1.5 * globalconf
.font
->height
;
392 wingeom
.y
= (area
.y
+ area
.height
) - wingeom
.height
;
398 wingeom
.y
= (area
.y
+ area
.height
- wingeom
.height
) / 2;
402 wingeom
.height
= wibox
->sw
.geometry
.height
> 0 ? wibox
->sw
.geometry
.height
: 1.5 * globalconf
.font
->height
;
403 wingeom
.width
= area
.width
;
404 wingeom
.y
= (area
.y
+ area
.height
) - wingeom
.height
;
411 wingeom
.x
+= area
.width
- wingeom
.width
;
414 wingeom
.x
+= (area
.width
- wingeom
.width
) / 2;
419 wingeom
.height
= wibox
->sw
.geometry
.height
> 0 ? wibox
->sw
.geometry
.height
: 1.5 * globalconf
.font
->height
;
420 wingeom
.width
= area
.width
;
428 wingeom
.x
+= area
.width
- wingeom
.width
;
431 wingeom
.x
+= (area
.width
- wingeom
.width
) / 2;
436 wingeom
.width
= MAX(1, wibox
->sw
.geometry
.width
);
437 wingeom
.height
= MAX(1, wibox
->sw
.geometry
.height
);
441 /* same window size and position ? */
442 if(wingeom
.width
!= wibox
->sw
.geometry
.width
443 || wingeom
.height
!= wibox
->sw
.geometry
.height
)
444 wibox_resize(wibox
, wingeom
.width
, wingeom
.height
);
446 if(wingeom
.x
!= wibox
->sw
.geometry
.x
447 || wingeom
.y
!= wibox
->sw
.geometry
.y
)
448 wibox_move(wibox
, wingeom
.x
, wingeom
.y
);
452 * \param wibox wibox to delete.
455 wibox_delete(wibox_t
**wibox
)
457 simplewindow_wipe(&(*wibox
)->sw
);
458 button_array_wipe(&(*wibox
)->buttons
);
459 luaL_unref(globalconf
.L
, LUA_REGISTRYINDEX
, (*wibox
)->widgets_table
);
460 widget_node_array_wipe(&(*wibox
)->widgets
);
464 /** Get a wibox by its window.
465 * \param w The window id.
466 * \return A wibox if found, NULL otherwise.
469 wibox_getbywin(xcb_window_t w
)
471 for(int screen
= 0; screen
< globalconf
.nscreen
; screen
++)
472 for(int i
= 0; i
< globalconf
.screens
[screen
].wiboxes
.len
; i
++)
474 wibox_t
*s
= globalconf
.screens
[screen
].wiboxes
.tab
[i
];
475 if(s
->sw
.window
== w
)
479 for(client_t
*c
= globalconf
.clients
; c
; c
= c
->next
)
480 if(c
->titlebar
&& c
->titlebar
->sw
.window
== w
)
487 * \param wibox The wibox to draw.
490 wibox_draw(wibox_t
*wibox
)
494 widget_render(&wibox
->widgets
, &wibox
->sw
.ctx
, wibox
->sw
.gc
,
496 wibox
->screen
, wibox
->sw
.orientation
,
497 wibox
->sw
.geometry
.x
, wibox
->sw
.geometry
.y
,
499 simplewindow_refresh_pixmap(&wibox
->sw
);
501 wibox
->need_update
= false;
504 wibox_systray_refresh(wibox
);
507 /** Refresh all wiboxes.
512 for(int screen
= 0; screen
< globalconf
.nscreen
; screen
++)
513 for(int i
= 0; i
< globalconf
.screens
[screen
].wiboxes
.len
; i
++)
515 wibox_t
*s
= globalconf
.screens
[screen
].wiboxes
.tab
[i
];
520 for(client_t
*c
= globalconf
.clients
; c
; c
= c
->next
)
521 if(c
->titlebar
&& c
->titlebar
->need_update
)
522 wibox_draw(c
->titlebar
);
525 /** Reposition all wiboxes.
528 wibox_update_positions(void)
530 for(int screen
= 0; screen
< globalconf
.nscreen
; screen
++)
531 for(int i
= 0; i
< globalconf
.screens
[screen
].wiboxes
.len
; i
++)
533 wibox_t
*s
= globalconf
.screens
[screen
].wiboxes
.tab
[i
];
534 wibox_position_update(s
);
538 /** Set a wibox visible or not.
539 * \param wibox The wibox.
540 * \param v The visible value.
543 wibox_setvisible(wibox_t
*wibox
, bool v
)
545 if(v
!= wibox
->isvisible
)
547 wibox
->isvisible
= v
;
549 if(wibox
->screen
!= SCREEN_UNDEF
)
553 xcb_map_window(globalconf
.connection
, wibox
->sw
.window
);
554 simplewindow_refresh_pixmap(&wibox
->sw
);
555 /* stack correctly the wibox */
559 xcb_unmap_window(globalconf
.connection
, wibox
->sw
.window
);
561 /* kick out systray if needed */
562 wibox_systray_refresh(wibox
);
564 /* All the other wibox and ourselves need to be repositioned */
565 wibox_array_t
*w
= &globalconf
.screens
[wibox
->screen
].wiboxes
;
566 for(int i
= 0; i
< w
->len
; i
++)
567 wibox_position_update(w
->tab
[i
]);
572 /** Remove a wibox from a screen.
573 * \param wibox Wibox to detach from screen.
576 wibox_detach(wibox_t
*wibox
)
578 if(wibox
->screen
!= SCREEN_UNDEF
)
582 /* save visible state */
583 v
= wibox
->isvisible
;
584 wibox
->isvisible
= false;
585 wibox_systray_refresh(wibox
);
586 wibox_position_update(wibox
);
587 /* restore position */
588 wibox
->isvisible
= v
;
590 simplewindow_wipe(&wibox
->sw
);
592 for(int i
= 0; i
< globalconf
.screens
[wibox
->screen
].wiboxes
.len
; i
++)
593 if(globalconf
.screens
[wibox
->screen
].wiboxes
.tab
[i
] == wibox
)
595 wibox_array_take(&globalconf
.screens
[wibox
->screen
].wiboxes
, i
);
598 globalconf
.screens
[wibox
->screen
].need_arrange
= true;
599 wibox
->screen
= SCREEN_UNDEF
;
605 * \param wibox The wibox to attach.
606 * \param s The screen to attach the wibox to.
609 wibox_attach(wibox_t
*wibox
, screen_t
*s
)
611 int phys_screen
= screen_virttophys(s
->index
);
615 wibox
->screen
= s
->index
;
617 wibox_array_append(&s
->wiboxes
, wibox_ref(&wibox
));
619 /* compute x/y/width/height if not set */
620 wibox_position_update(wibox
);
622 simplewindow_init(&wibox
->sw
, phys_screen
,
624 wibox
->sw
.border
.width
,
625 wibox
->sw
.orientation
,
626 &wibox
->sw
.ctx
.fg
, &wibox
->sw
.ctx
.bg
);
628 simplewindow_border_color_set(&wibox
->sw
, &wibox
->sw
.border
.color
);
630 simplewindow_cursor_set(&wibox
->sw
,
631 xcursor_new(globalconf
.connection
, xcursor_font_fromstr(wibox
->cursor
)));
633 /* All the other wibox and ourselves need to be repositioned */
634 for(int i
= 0; i
< s
->wiboxes
.len
; i
++)
635 wibox_position_update(s
->wiboxes
.tab
[i
]);
637 ewmh_update_workarea(screen_virttophys(s
->index
));
641 /* draw it right now once to avoid garbage shown */
643 xcb_map_window(globalconf
.connection
, wibox
->sw
.window
);
644 simplewindow_refresh_pixmap(&wibox
->sw
);
645 /* stack correctly the wibox */
649 wibox
->need_update
= true;
652 /** Create a new wibox.
653 * \param L The Lua VM state.
656 * \lparam A table with optionaly defined values:
657 * position, align, fg, bg, border_width, border_color, width and height.
658 * \lreturn A brand new wibox.
661 luaA_wibox_new(lua_State
*L
)
666 xcolor_init_request_t reqs
[3];
667 int8_t i
, reqs_nbr
= -1;
669 luaA_checktable(L
, 2);
671 w
= p_new(wibox_t
, 1);
672 w
->widgets_table
= LUA_REFNIL
;
674 w
->sw
.ctx
.fg
= globalconf
.colors
.fg
;
675 if((buf
= luaA_getopt_lstring(L
, 2, "fg", NULL
, &len
)))
676 reqs
[++reqs_nbr
] = xcolor_init_unchecked(&w
->sw
.ctx
.fg
, buf
, len
);
678 w
->sw
.ctx
.bg
= globalconf
.colors
.bg
;
679 if((buf
= luaA_getopt_lstring(L
, 2, "bg", NULL
, &len
)))
680 reqs
[++reqs_nbr
] = xcolor_init_unchecked(&w
->sw
.ctx
.bg
, buf
, len
);
682 w
->sw
.border
.color
= globalconf
.colors
.bg
;
683 if((buf
= luaA_getopt_lstring(L
, 2, "border_color", NULL
, &len
)))
684 reqs
[++reqs_nbr
] = xcolor_init_unchecked(&w
->sw
.border
.color
, buf
, len
);
686 buf
= luaA_getopt_lstring(L
, 2, "align", "left", &len
);
687 w
->align
= draw_align_fromstr(buf
, len
);
689 w
->sw
.border
.width
= luaA_getopt_number(L
, 2, "border_width", 0);
691 buf
= luaA_getopt_lstring(L
, 2, "position", "top", &len
);
693 switch((w
->position
= position_fromstr(buf
, len
)))
698 simplewindow_orientation_set(&w
->sw
, East
);
701 simplewindow_orientation_set(&w
->sw
, North
);
704 simplewindow_orientation_set(&w
->sw
, South
);
708 /* recompute position */
709 wibox_position_update(w
);
711 w
->sw
.geometry
.width
= luaA_getopt_number(L
, 2, "width", 0);
712 w
->sw
.geometry
.height
= luaA_getopt_number(L
, 2, "height", 0);
714 w
->screen
= SCREEN_UNDEF
;
716 w
->cursor
= a_strdup("left_ptr");
718 for(i
= 0; i
<= reqs_nbr
; i
++)
719 xcolor_init_reply(reqs
[i
]);
721 return luaA_wibox_userdata_new(L
, w
);
724 /** Rebuild wibox widgets list.
725 * \param L The Lua VM state.
726 * \param wibox The wibox.
729 wibox_widgets_table_build(lua_State
*L
, wibox_t
*wibox
)
731 widget_node_array_wipe(&wibox
->widgets
);
732 widget_node_array_init(&wibox
->widgets
);
733 luaA_table2widgets(L
, &wibox
->widgets
);
734 wibox
->mouse_over
= NULL
;
735 wibox
->need_update
= true;
738 /** Check if a wibox widget table has an item.
739 * \param L The Lua VM state.
740 * \param wibox The wibox.
741 * \param item The item to look for.
744 luaA_wibox_hasitem(lua_State
*L
, wibox_t
*wibox
, const void *item
)
746 if(wibox
->widgets_table
!= LUA_REFNIL
)
748 lua_rawgeti(globalconf
.L
, LUA_REGISTRYINDEX
, wibox
->widgets_table
);
749 if(lua_topointer(L
, -1) == item
|| luaA_hasitem(L
, item
))
755 /** Invalidate a wibox by a Lua object (table, etc).
756 * \param L The Lua VM state.
757 * \param item The object identifier.
760 luaA_wibox_invalidate_byitem(lua_State
*L
, const void *item
)
762 for(int screen
= 0; screen
< globalconf
.nscreen
; screen
++)
763 for(int i
= 0; i
< globalconf
.screens
[screen
].wiboxes
.len
; i
++)
765 wibox_t
*wibox
= globalconf
.screens
[screen
].wiboxes
.tab
[i
];
766 if(luaA_wibox_hasitem(L
, wibox
, item
))
768 /* recompute widget node list */
769 wibox_widgets_table_build(L
, wibox
);
770 lua_pop(L
, 1); /* remove widgets table */
775 for(client_t
*c
= globalconf
.clients
; c
; c
= c
->next
)
776 if(c
->titlebar
&& luaA_wibox_hasitem(L
, c
->titlebar
, item
))
778 /* recompute widget node list */
779 wibox_widgets_table_build(L
, c
->titlebar
);
780 lua_pop(L
, 1); /* remove widgets table */
785 * \param L The Lua VM state.
786 * \return The number of elements pushed on stack.
788 * \lfield screen Screen number.
789 * \lfield client The client attached to this titlebar.
790 * \lfield border_width Border width.
791 * \lfield border_color Border color.
792 * \lfield align The alignment.
793 * \lfield fg Foreground color.
794 * \lfield bg Background color.
795 * \lfield position The position.
796 * \lfield ontop On top of other windows.
797 * \lfield cursor The mouse cursor.
800 luaA_wibox_index(lua_State
*L
)
803 wibox_t
**wibox
= luaA_checkudata(L
, 1, "wibox");
804 const char *attr
= luaL_checklstring(L
, 2, &len
);
806 if(luaA_usemetatable(L
, 1, 2))
809 switch(a_tokenize(attr
, len
))
814 lua_pushboolean(L
, (*wibox
)->isvisible
);
817 if((c
= client_getbytitlebar(*wibox
)))
818 return luaA_client_userdata_new(L
, c
);
822 if((*wibox
)->screen
== SCREEN_UNDEF
)
824 lua_pushnumber(L
, (*wibox
)->screen
+ 1);
826 case A_TK_BORDER_WIDTH
:
827 lua_pushnumber(L
, (*wibox
)->sw
.border
.width
);
829 case A_TK_BORDER_COLOR
:
830 luaA_pushcolor(L
, &(*wibox
)->sw
.border
.color
);
833 lua_pushstring(L
, draw_align_tostr((*wibox
)->align
));
836 luaA_pushcolor(L
, &(*wibox
)->sw
.ctx
.fg
);
839 luaA_pushcolor(L
, &(*wibox
)->sw
.ctx
.bg
);
842 lua_pushstring(L
, position_tostr((*wibox
)->position
));
845 lua_pushboolean(L
, (*wibox
)->ontop
);
847 case A_TK_ORIENTATION
:
848 lua_pushstring(L
, orientation_tostr((*wibox
)->sw
.orientation
));
851 if((*wibox
)->widgets_table
!= LUA_REFNIL
)
852 lua_rawgeti(L
, LUA_REGISTRYINDEX
, (*wibox
)->widgets_table
);
857 lua_pushstring(L
, (*wibox
)->cursor
);
866 /* Set or get the wibox geometry.
867 * \param L The Lua VM state.
868 * \return The number of elements pushed on stack.
870 * \lparam An optional table with wibox geometry.
871 * \lreturn The wibox geometry.
874 luaA_wibox_geometry(lua_State
*L
)
876 wibox_t
**wibox
= luaA_checkudata(L
, 1, "wibox");
878 if(lua_gettop(L
) == 2)
882 luaA_checktable(L
, 2);
883 wingeom
.x
= luaA_getopt_number(L
, 2, "x", (*wibox
)->sw
.geometry
.x
);
884 wingeom
.y
= luaA_getopt_number(L
, 2, "y", (*wibox
)->sw
.geometry
.y
);
885 wingeom
.width
= luaA_getopt_number(L
, 2, "width", (*wibox
)->sw
.geometry
.width
);
886 wingeom
.height
= luaA_getopt_number(L
, 2, "height", (*wibox
)->sw
.geometry
.height
);
888 switch((*wibox
)->type
)
890 case WIBOX_TYPE_TITLEBAR
:
891 wibox_resize(*wibox
, wingeom
.width
, wingeom
.height
);
893 case WIBOX_TYPE_NORMAL
:
894 if((*wibox
)->position
== Floating
)
895 wibox_moveresize(*wibox
, wingeom
);
896 else if(wingeom
.width
!= (*wibox
)->sw
.geometry
.width
897 || wingeom
.height
!= (*wibox
)->sw
.geometry
.height
)
899 wibox_resize(*wibox
, wingeom
.width
, wingeom
.height
);
900 globalconf
.screens
[(*wibox
)->screen
].need_arrange
= true;
906 return luaA_pusharea(L
, (*wibox
)->sw
.geometry
);
910 * \param L The Lua VM state.
911 * \return The number of elements pushed on stack.
914 luaA_wibox_newindex(lua_State
*L
)
917 wibox_t
**wibox
= luaA_checkudata(L
, 1, "wibox");
918 const char *buf
, *attr
= luaL_checklstring(L
, 2, &len
);
921 switch((tok
= a_tokenize(attr
, len
)))
926 if((buf
= luaL_checklstring(L
, 3, &len
)))
927 if(xcolor_init_reply(xcolor_init_unchecked(&(*wibox
)->sw
.ctx
.fg
, buf
, len
)))
928 (*wibox
)->need_update
= true;
931 if((buf
= luaL_checklstring(L
, 3, &len
)))
932 if(xcolor_init_reply(xcolor_init_unchecked(&(*wibox
)->sw
.ctx
.bg
, buf
, len
)))
933 (*wibox
)->need_update
= true;
936 buf
= luaL_checklstring(L
, 3, &len
);
937 (*wibox
)->align
= draw_align_fromstr(buf
, len
);
938 switch((*wibox
)->type
)
940 case WIBOX_TYPE_NORMAL
:
941 wibox_position_update(*wibox
);
943 case WIBOX_TYPE_TITLEBAR
:
944 titlebar_update_geometry(client_getbytitlebar(*wibox
));
949 switch((*wibox
)->type
)
951 case WIBOX_TYPE_TITLEBAR
:
952 return luaA_titlebar_newindex(L
, *wibox
, tok
);
953 case WIBOX_TYPE_NORMAL
:
954 if((buf
= luaL_checklstring(L
, 3, &len
)))
955 wibox_setposition(*wibox
, position_fromstr(buf
, len
));
962 titlebar_client_detach(client_getbytitlebar(*wibox
));
965 client_t
**c
= luaA_checkudata(L
, 3, "client");
966 titlebar_client_attach(*c
, *wibox
);
970 if((buf
= luaL_checkstring(L
, 3)))
972 uint16_t cursor_font
= xcursor_font_fromstr(buf
);
975 xcb_cursor_t cursor
= xcursor_new(globalconf
.connection
, cursor_font
);
976 p_delete(&(*wibox
)->cursor
);
977 (*wibox
)->cursor
= a_strdup(buf
);
978 simplewindow_cursor_set(&(*wibox
)->sw
, cursor
);
985 wibox_detach(*wibox
);
986 titlebar_client_detach(client_getbytitlebar(*wibox
));
990 int screen
= luaL_checknumber(L
, 3) - 1;
991 luaA_checkscreen(screen
);
992 if(screen
!= (*wibox
)->screen
)
994 titlebar_client_detach(client_getbytitlebar(*wibox
));
995 wibox_attach(*wibox
, &globalconf
.screens
[screen
]);
1000 b
= luaA_checkboolean(L
, 3);
1001 if(b
!= (*wibox
)->ontop
)
1003 (*wibox
)->ontop
= b
;
1007 case A_TK_ORIENTATION
:
1008 if((buf
= luaL_checklstring(L
, 3, &len
)))
1010 simplewindow_orientation_set(&(*wibox
)->sw
, orientation_fromstr(buf
, len
));
1011 (*wibox
)->need_update
= true;
1014 case A_TK_BORDER_COLOR
:
1015 if((buf
= luaL_checklstring(L
, 3, &len
)))
1016 if(xcolor_init_reply(xcolor_init_unchecked(&(*wibox
)->sw
.border
.color
, buf
, len
)))
1017 if((*wibox
)->sw
.window
)
1018 simplewindow_border_color_set(&(*wibox
)->sw
, &(*wibox
)->sw
.border
.color
);
1021 b
= luaA_checkboolean(L
, 3);
1022 if(b
!= (*wibox
)->isvisible
)
1023 switch((*wibox
)->type
)
1025 case WIBOX_TYPE_NORMAL
:
1026 wibox_setvisible(*wibox
, b
);
1028 case WIBOX_TYPE_TITLEBAR
:
1029 titlebar_set_visible(*wibox
, b
);
1034 if(luaA_isloop(L
, 3))
1036 luaA_warn(L
, "table is looping, cannot use this as widget table");
1039 luaA_register(L
, 3, &(*wibox
)->widgets_table
);
1040 /* recompute widget node list */
1041 wibox_widgets_table_build(L
, *wibox
);
1042 luaA_table2wtable(L
);
1045 switch((*wibox
)->type
)
1047 case WIBOX_TYPE_TITLEBAR
:
1048 return luaA_titlebar_newindex(L
, *wibox
, tok
);
1049 case WIBOX_TYPE_NORMAL
:
1057 /** Get or set mouse buttons bindings to a wibox.
1058 * \param L The Lua VM state.
1061 * \lparam An array of mouse button bindings objects, or nothing.
1062 * \return The array of mouse button bindings objects of this wibox.
1065 luaA_wibox_buttons(lua_State
*L
)
1067 wibox_t
**wibox
= luaA_checkudata(L
, 1, "wibox");
1068 button_array_t
*buttons
= &(*wibox
)->buttons
;
1070 if(lua_gettop(L
) == 2)
1072 luaA_button_array_set(L
, 2, buttons
);
1076 return luaA_button_array_get(L
, buttons
);
1079 const struct luaL_reg awesome_wibox_methods
[] =
1081 { "__call", luaA_wibox_new
},
1084 const struct luaL_reg awesome_wibox_meta
[] =
1086 { "buttons", luaA_wibox_buttons
},
1087 { "geometry", luaA_wibox_geometry
},
1088 { "__index", luaA_wibox_index
},
1089 { "__newindex", luaA_wibox_newindex
},
1090 { "__gc", luaA_wibox_gc
},
1091 { "__eq", luaA_wibox_eq
},
1092 { "__tostring", luaA_wibox_tostring
},
1096 // vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80