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.
28 #include "common/xcursor.h"
31 extern awesome_t globalconf
;
33 DO_LUA_NEW(extern, wibox_t
, wibox
, "wibox", wibox_ref
)
34 DO_LUA_GC(wibox_t
, wibox
, "wibox", wibox_unref
)
35 DO_LUA_EQ(wibox_t
, wibox
, "wibox")
38 wibox_move(wibox_t
*wibox
, int16_t x
, int16_t y
)
42 simplewindow_move(&wibox
->sw
, x
, y
);
43 wibox
->screen
= screen_getbycoord(wibox
->screen
, x
, y
);
47 wibox
->sw
.geometry
.x
= x
;
48 wibox
->sw
.geometry
.y
= y
;
53 wibox_resize(wibox_t
*wibox
, uint16_t width
, uint16_t height
)
56 simplewindow_resize(&wibox
->sw
, width
, height
);
59 wibox
->sw
.geometry
.width
= width
;
60 wibox
->sw
.geometry
.height
= height
;
62 wibox
->need_update
= true;
63 wibox
->mouse_over
= NULL
;
67 wibox_setposition(wibox_t
*wibox
, position_t p
)
69 if(p
!= wibox
->position
)
71 switch((wibox
->position
= p
))
76 simplewindow_orientation_set(&wibox
->sw
, East
);
79 simplewindow_orientation_set(&wibox
->sw
, North
);
82 simplewindow_orientation_set(&wibox
->sw
, South
);
85 /* reset width/height to 0 */
86 if(wibox
->position
!= Floating
)
87 wibox
->sw
.geometry
.width
= wibox
->sw
.geometry
.height
= 0;
89 /* recompute position */
90 wibox_position_update(wibox
);
92 /* reset all wibox position */
93 wibox_array_t
*w
= &globalconf
.screens
[wibox
->screen
].wiboxes
;
94 for(int i
= 0; i
< w
->len
; i
++)
95 wibox_position_update(w
->tab
[i
]);
97 ewmh_update_workarea(screen_virttophys(wibox
->screen
));
99 wibox
->need_update
= true;
100 wibox
->mouse_over
= NULL
;
104 /** Kick out systray windows.
105 * \param phys_screen Physical screen number.
108 wibox_systray_kickout(int phys_screen
)
110 xcb_screen_t
*s
= xutil_screen_get(globalconf
.connection
, phys_screen
);
112 if(globalconf
.screens
[phys_screen
].systray
.parent
!= s
->root
)
114 /* Who! Check that we're not deleting a wibox with a systray, because it
115 * may be its parent. If so, we reparent to root before, otherwise it will
117 xcb_reparent_window(globalconf
.connection
,
118 globalconf
.screens
[phys_screen
].systray
.window
,
119 s
->root
, -512, -512);
121 globalconf
.screens
[phys_screen
].systray
.parent
= s
->root
;
126 wibox_systray_refresh(wibox_t
*wibox
)
128 if(wibox
->screen
== SCREEN_UNDEF
)
131 for(int i
= 0; i
< wibox
->widgets
.len
; i
++)
133 widget_node_t
*systray
= &wibox
->widgets
.tab
[i
];
134 if(systray
->widget
->type
== widget_systray
)
136 uint32_t config_back
[] = { wibox
->sw
.ctx
.bg
.pixel
};
137 uint32_t config_win_vals
[4];
138 uint32_t config_win_vals_off
[2] = { -512, -512 };
141 int phys_screen
= wibox
->sw
.ctx
.phys_screen
;
144 && systray
->widget
->isvisible
145 && systray
->geometry
.width
)
147 pos
= wibox
->position
;
149 /* Set background of the systray window. */
150 xcb_change_window_attributes(globalconf
.connection
,
151 globalconf
.screens
[phys_screen
].systray
.window
,
152 XCB_CW_BACK_PIXEL
, config_back
);
154 xcb_map_window(globalconf
.connection
, globalconf
.screens
[phys_screen
].systray
.window
);
156 switch(wibox
->position
)
159 config_win_vals
[0] = systray
->geometry
.y
;
160 config_win_vals
[1] = wibox
->sw
.geometry
.height
- systray
->geometry
.x
- systray
->geometry
.width
;
161 config_win_vals
[2] = systray
->geometry
.height
;
162 config_win_vals
[3] = systray
->geometry
.width
;
165 config_win_vals
[0] = systray
->geometry
.y
;
166 config_win_vals
[1] = systray
->geometry
.x
;
167 config_win_vals
[2] = systray
->geometry
.height
;
168 config_win_vals
[3] = systray
->geometry
.width
;
171 config_win_vals
[0] = systray
->geometry
.x
;
172 config_win_vals
[1] = systray
->geometry
.y
;
173 config_win_vals
[2] = systray
->geometry
.width
;
174 config_win_vals
[3] = systray
->geometry
.height
;
178 if(globalconf
.screens
[phys_screen
].systray
.parent
!= wibox
->sw
.window
)
180 xcb_reparent_window(globalconf
.connection
,
181 globalconf
.screens
[phys_screen
].systray
.window
,
183 config_win_vals
[0], config_win_vals
[1]);
184 globalconf
.screens
[phys_screen
].systray
.parent
= wibox
->sw
.window
;
186 xcb_configure_window(globalconf
.connection
,
187 globalconf
.screens
[phys_screen
].systray
.window
,
189 | XCB_CONFIG_WINDOW_Y
190 | XCB_CONFIG_WINDOW_WIDTH
191 | XCB_CONFIG_WINDOW_HEIGHT
,
193 /* width = height = systray height */
194 config_win_vals
[2] = config_win_vals
[3] = systray
->geometry
.height
;
195 config_win_vals
[0] = 0;
198 return wibox_systray_kickout(phys_screen
);
203 config_win_vals
[1] = systray
->geometry
.width
- config_win_vals
[3];
204 for(int j
= 0; j
< globalconf
.embedded
.len
; j
++)
206 em
= &globalconf
.embedded
.tab
[j
];
207 if(em
->phys_screen
== phys_screen
)
209 if(config_win_vals
[1] - config_win_vals
[2] >= (uint32_t) wibox
->sw
.geometry
.y
)
211 xcb_map_window(globalconf
.connection
, em
->win
);
212 xcb_configure_window(globalconf
.connection
, em
->win
,
214 | XCB_CONFIG_WINDOW_Y
215 | XCB_CONFIG_WINDOW_WIDTH
216 | XCB_CONFIG_WINDOW_HEIGHT
,
218 config_win_vals
[1] -= config_win_vals
[3];
221 xcb_configure_window(globalconf
.connection
, em
->win
,
223 | XCB_CONFIG_WINDOW_Y
,
224 config_win_vals_off
);
229 config_win_vals
[1] = 0;
230 for(int j
= 0; j
< globalconf
.embedded
.len
; j
++)
232 em
= &globalconf
.embedded
.tab
[j
];
233 if(em
->phys_screen
== phys_screen
)
235 if(config_win_vals
[1] + config_win_vals
[3] <= (uint32_t) wibox
->sw
.geometry
.y
+ wibox
->sw
.geometry
.width
)
237 xcb_map_window(globalconf
.connection
, em
->win
);
238 xcb_configure_window(globalconf
.connection
, em
->win
,
240 | XCB_CONFIG_WINDOW_Y
241 | XCB_CONFIG_WINDOW_WIDTH
242 | XCB_CONFIG_WINDOW_HEIGHT
,
244 config_win_vals
[1] += config_win_vals
[3];
247 xcb_configure_window(globalconf
.connection
, em
->win
,
249 | XCB_CONFIG_WINDOW_Y
,
250 config_win_vals_off
);
257 config_win_vals
[1] = 0;
258 for(int j
= 0; j
< globalconf
.embedded
.len
; j
++)
260 em
= &globalconf
.embedded
.tab
[j
];
261 if(em
->phys_screen
== phys_screen
)
263 /* if(x + width < systray.x + systray.width) */
264 if(config_win_vals
[0] + config_win_vals
[2] <= (uint32_t) AREA_RIGHT(systray
->geometry
) + wibox
->sw
.geometry
.x
)
266 xcb_map_window(globalconf
.connection
, em
->win
);
267 xcb_configure_window(globalconf
.connection
, em
->win
,
269 | XCB_CONFIG_WINDOW_Y
270 | XCB_CONFIG_WINDOW_WIDTH
271 | XCB_CONFIG_WINDOW_HEIGHT
,
273 config_win_vals
[0] += config_win_vals
[2];
276 xcb_configure_window(globalconf
.connection
, em
->win
,
278 | XCB_CONFIG_WINDOW_Y
,
279 config_win_vals_off
);
289 /** Update the wibox position. It deletes every wibox resources and
291 * \param wibox The wibox.
294 wibox_position_update(wibox_t
*wibox
)
296 area_t area
, wingeom
= wibox
->sw
.geometry
;
299 globalconf
.screens
[wibox
->screen
].need_arrange
= true;
301 area
= screen_area_get(wibox
->screen
, NULL
,
302 &globalconf
.screens
[wibox
->screen
].padding
, true);
304 /* Top and Bottom wibox_t have prio */
305 if(wibox
->position
!= Floating
)
306 for(int i
= 0; i
< globalconf
.screens
[wibox
->screen
].wiboxes
.len
; i
++)
308 wibox_t
*w
= globalconf
.screens
[wibox
->screen
].wiboxes
.tab
[i
];
309 /* Ignore every wibox after me that is in the same position */
315 else if((ignore
&& wibox
->position
== w
->position
) || !w
->isvisible
)
322 switch(wibox
->position
)
325 area
.x
+= wibox
->sw
.geometry
.height
;
332 switch(wibox
->position
)
335 area
.x
-= wibox
->sw
.geometry
.height
;
342 switch(wibox
->position
)
345 area
.y
+= w
->sw
.geometry
.height
;
349 area
.height
-= w
->sw
.geometry
.height
;
350 area
.y
+= w
->sw
.geometry
.height
;
357 switch(wibox
->position
)
360 area
.y
-= w
->sw
.geometry
.height
;
364 area
.height
-= w
->sw
.geometry
.height
;
373 /* The "length" of a wibox is always chosen to be the optimal size (non-floating).
374 * The "width" of a wibox is kept if it exists.
376 switch(wibox
->position
)
379 wingeom
.height
= area
.height
;
380 wingeom
.width
= wibox
->sw
.geometry
.width
> 0 ? wibox
->sw
.geometry
.width
: 1.5 * globalconf
.font
->height
;
381 wingeom
.x
= area
.x
+ area
.width
- wingeom
.width
;
388 wingeom
.y
= area
.y
+ area
.height
- wingeom
.height
;
391 wingeom
.y
= (area
.y
+ area
.height
- wingeom
.height
) / 2;
396 wingeom
.height
= area
.height
;
397 wingeom
.width
= wibox
->sw
.geometry
.width
> 0 ? wibox
->sw
.geometry
.width
: 1.5 * globalconf
.font
->height
;
402 wingeom
.y
= (area
.y
+ area
.height
) - wingeom
.height
;
408 wingeom
.y
= (area
.y
+ area
.height
- wingeom
.height
) / 2;
412 wingeom
.height
= wibox
->sw
.geometry
.height
> 0 ? wibox
->sw
.geometry
.height
: 1.5 * globalconf
.font
->height
;
413 wingeom
.width
= area
.width
;
414 wingeom
.y
= (area
.y
+ area
.height
) - wingeom
.height
;
421 wingeom
.x
+= area
.width
- wingeom
.width
;
424 wingeom
.x
+= (area
.width
- wingeom
.width
) / 2;
429 wingeom
.height
= wibox
->sw
.geometry
.height
> 0 ? wibox
->sw
.geometry
.height
: 1.5 * globalconf
.font
->height
;
430 wingeom
.width
= area
.width
;
438 wingeom
.x
+= area
.width
- wingeom
.width
;
441 wingeom
.x
+= (area
.width
- wingeom
.width
) / 2;
446 wingeom
.width
= MAX(1, wibox
->sw
.geometry
.width
);
447 wingeom
.height
= MAX(1, wibox
->sw
.geometry
.height
);
451 /* same window size and position ? */
452 if(wingeom
.width
!= wibox
->sw
.geometry
.width
453 || wingeom
.height
!= wibox
->sw
.geometry
.height
)
454 wibox_resize(wibox
, wingeom
.width
, wingeom
.height
);
456 if(wingeom
.x
!= wibox
->sw
.geometry
.x
457 || wingeom
.y
!= wibox
->sw
.geometry
.y
)
458 wibox_move(wibox
, wingeom
.x
, wingeom
.y
);
462 * \param wibox wibox to delete.
465 wibox_delete(wibox_t
**wibox
)
467 simplewindow_wipe(&(*wibox
)->sw
);
468 button_array_wipe(&(*wibox
)->buttons
);
469 luaL_unref(globalconf
.L
, LUA_REGISTRYINDEX
, (*wibox
)->widgets_table
);
470 widget_node_array_wipe(&(*wibox
)->widgets
);
474 /** Get a wibox by its window.
475 * \param w The window id.
476 * \return A wibox if found, NULL otherwise.
479 wibox_getbywin(xcb_window_t w
)
481 for(int screen
= 0; screen
< globalconf
.nscreen
; screen
++)
482 for(int i
= 0; i
< globalconf
.screens
[screen
].wiboxes
.len
; i
++)
484 wibox_t
*s
= globalconf
.screens
[screen
].wiboxes
.tab
[i
];
485 if(s
->sw
.window
== w
)
489 for(client_t
*c
= globalconf
.clients
; c
; c
= c
->next
)
490 if(c
->titlebar
&& c
->titlebar
->sw
.window
== w
)
497 * \param wibox The wibox to draw.
500 wibox_draw(wibox_t
*wibox
)
504 widget_render(wibox
);
505 simplewindow_refresh_pixmap(&wibox
->sw
);
507 wibox
->need_update
= false;
510 wibox_systray_refresh(wibox
);
513 /** Refresh all wiboxes.
518 for(int screen
= 0; screen
< globalconf
.nscreen
; screen
++)
519 for(int i
= 0; i
< globalconf
.screens
[screen
].wiboxes
.len
; i
++)
521 wibox_t
*s
= globalconf
.screens
[screen
].wiboxes
.tab
[i
];
526 for(client_t
*c
= globalconf
.clients
; c
; c
= c
->next
)
527 if(c
->titlebar
&& c
->titlebar
->need_update
)
528 wibox_draw(c
->titlebar
);
531 /** Reposition all wiboxes.
534 wibox_update_positions(void)
536 for(int screen
= 0; screen
< globalconf
.nscreen
; screen
++)
537 for(int i
= 0; i
< globalconf
.screens
[screen
].wiboxes
.len
; i
++)
539 wibox_t
*s
= globalconf
.screens
[screen
].wiboxes
.tab
[i
];
540 wibox_position_update(s
);
544 /** Set a wibox visible or not.
545 * \param wibox The wibox.
546 * \param v The visible value.
549 wibox_setvisible(wibox_t
*wibox
, bool v
)
551 if(v
!= wibox
->isvisible
)
553 wibox
->isvisible
= v
;
554 wibox
->mouse_over
= NULL
;
556 if(wibox
->screen
!= SCREEN_UNDEF
)
560 xcb_map_window(globalconf
.connection
, wibox
->sw
.window
);
561 simplewindow_refresh_pixmap(&wibox
->sw
);
562 /* stack correctly the wibox */
566 xcb_unmap_window(globalconf
.connection
, wibox
->sw
.window
);
568 /* kick out systray if needed */
569 wibox_systray_refresh(wibox
);
571 /* All the other wibox and ourselves need to be repositioned */
572 wibox_array_t
*w
= &globalconf
.screens
[wibox
->screen
].wiboxes
;
573 for(int i
= 0; i
< w
->len
; i
++)
574 wibox_position_update(w
->tab
[i
]);
579 /** Remove a wibox from a screen.
580 * \param wibox Wibox to detach from screen.
583 wibox_detach(wibox_t
*wibox
)
585 if(wibox
->screen
!= SCREEN_UNDEF
)
589 /* save visible state */
590 v
= wibox
->isvisible
;
591 wibox
->isvisible
= false;
592 wibox_systray_refresh(wibox
);
593 wibox_position_update(wibox
);
594 /* restore position */
595 wibox
->isvisible
= v
;
597 wibox
->mouse_over
= NULL
;
599 simplewindow_wipe(&wibox
->sw
);
601 for(int i
= 0; i
< globalconf
.screens
[wibox
->screen
].wiboxes
.len
; i
++)
602 if(globalconf
.screens
[wibox
->screen
].wiboxes
.tab
[i
] == wibox
)
604 wibox_array_take(&globalconf
.screens
[wibox
->screen
].wiboxes
, i
);
607 globalconf
.screens
[wibox
->screen
].need_arrange
= true;
608 wibox
->screen
= SCREEN_UNDEF
;
614 * \param wibox The wibox to attach.
615 * \param s The screen to attach the wibox to.
618 wibox_attach(wibox_t
*wibox
, screen_t
*s
)
620 int phys_screen
= screen_virttophys(s
->index
);
624 /* Set the wibox screen */
625 wibox
->screen
= s
->index
;
627 /* Check that the wibox coordinates matches the screen. */
628 int cscreen
= screen_getbycoord(wibox
->screen
, wibox
->sw
.geometry
.x
, wibox
->sw
.geometry
.y
);
630 /* If it does not match, move it to the screen coordinates */
631 if(cscreen
!= wibox
->screen
)
632 wibox_move(wibox
, s
->geometry
.x
, s
->geometry
.y
);
634 wibox_array_append(&s
->wiboxes
, wibox_ref(&wibox
));
636 /* compute x/y/width/height if not set */
637 wibox_position_update(wibox
);
639 simplewindow_init(&wibox
->sw
, phys_screen
,
641 wibox
->sw
.border
.width
,
642 wibox
->sw
.orientation
,
643 &wibox
->sw
.ctx
.fg
, &wibox
->sw
.ctx
.bg
);
645 simplewindow_border_color_set(&wibox
->sw
, &wibox
->sw
.border
.color
);
647 simplewindow_cursor_set(&wibox
->sw
,
648 xcursor_new(globalconf
.connection
, xcursor_font_fromstr(wibox
->cursor
)));
650 /* All the other wibox and ourselves need to be repositioned */
651 for(int i
= 0; i
< s
->wiboxes
.len
; i
++)
652 wibox_position_update(s
->wiboxes
.tab
[i
]);
654 ewmh_update_workarea(screen_virttophys(s
->index
));
658 /* draw it right now once to avoid garbage shown */
660 xcb_map_window(globalconf
.connection
, wibox
->sw
.window
);
661 simplewindow_refresh_pixmap(&wibox
->sw
);
662 /* stack correctly the wibox */
666 wibox
->need_update
= true;
669 /** Create a new wibox.
670 * \param L The Lua VM state.
673 * \lparam A table with optionaly defined values:
674 * position, align, fg, bg, border_width, border_color, ontop, width and height.
675 * \lreturn A brand new wibox.
678 luaA_wibox_new(lua_State
*L
)
683 xcolor_init_request_t reqs
[3];
684 int i
, reqs_nbr
= -1;
686 luaA_checktable(L
, 2);
688 w
= p_new(wibox_t
, 1);
689 w
->widgets_table
= LUA_REFNIL
;
691 w
->sw
.ctx
.fg
= globalconf
.colors
.fg
;
692 if((buf
= luaA_getopt_lstring(L
, 2, "fg", NULL
, &len
)))
693 reqs
[++reqs_nbr
] = xcolor_init_unchecked(&w
->sw
.ctx
.fg
, buf
, len
);
695 w
->sw
.ctx
.bg
= globalconf
.colors
.bg
;
696 if((buf
= luaA_getopt_lstring(L
, 2, "bg", NULL
, &len
)))
697 reqs
[++reqs_nbr
] = xcolor_init_unchecked(&w
->sw
.ctx
.bg
, buf
, len
);
699 w
->sw
.border
.color
= globalconf
.colors
.bg
;
700 if((buf
= luaA_getopt_lstring(L
, 2, "border_color", NULL
, &len
)))
701 reqs
[++reqs_nbr
] = xcolor_init_unchecked(&w
->sw
.border
.color
, buf
, len
);
703 w
->ontop
= luaA_getopt_boolean(L
, 2, "ontop", false);
705 buf
= luaA_getopt_lstring(L
, 2, "align", "left", &len
);
706 w
->align
= draw_align_fromstr(buf
, len
);
708 w
->sw
.border
.width
= luaA_getopt_number(L
, 2, "border_width", 0);
710 buf
= luaA_getopt_lstring(L
, 2, "position", "top", &len
);
712 switch((w
->position
= position_fromstr(buf
, len
)))
717 simplewindow_orientation_set(&w
->sw
, East
);
720 simplewindow_orientation_set(&w
->sw
, North
);
723 simplewindow_orientation_set(&w
->sw
, South
);
727 /* recompute position */
728 wibox_position_update(w
);
730 w
->sw
.geometry
.x
= luaA_getopt_number(L
, 2, "x", 0);
731 w
->sw
.geometry
.y
= luaA_getopt_number(L
, 2, "y", 0);
732 w
->sw
.geometry
.width
= luaA_getopt_number(L
, 2, "width", 0);
733 w
->sw
.geometry
.height
= luaA_getopt_number(L
, 2, "height", 0);
735 w
->screen
= SCREEN_UNDEF
;
737 w
->cursor
= a_strdup("left_ptr");
739 for(i
= 0; i
<= reqs_nbr
; i
++)
740 xcolor_init_reply(reqs
[i
]);
742 return luaA_wibox_userdata_new(L
, w
);
745 /** Rebuild wibox widgets list.
746 * \param L The Lua VM state.
747 * \param wibox The wibox.
750 wibox_widgets_table_build(lua_State
*L
, wibox_t
*wibox
)
752 widget_node_array_wipe(&wibox
->widgets
);
753 widget_node_array_init(&wibox
->widgets
);
754 luaA_table2widgets(L
, &wibox
->widgets
);
755 wibox
->mouse_over
= NULL
;
756 wibox
->need_update
= true;
759 /** Check if a wibox widget table has an item.
760 * \param L The Lua VM state.
761 * \param wibox The wibox.
762 * \param item The item to look for.
765 luaA_wibox_hasitem(lua_State
*L
, wibox_t
*wibox
, const void *item
)
767 if(wibox
->widgets_table
!= LUA_REFNIL
)
769 lua_rawgeti(globalconf
.L
, LUA_REGISTRYINDEX
, wibox
->widgets_table
);
770 if(lua_topointer(L
, -1) == item
|| luaA_hasitem(L
, item
))
776 /** Invalidate a wibox by a Lua object (table, etc).
777 * \param L The Lua VM state.
778 * \param item The object identifier.
781 luaA_wibox_invalidate_byitem(lua_State
*L
, const void *item
)
783 for(int screen
= 0; screen
< globalconf
.nscreen
; screen
++)
784 for(int i
= 0; i
< globalconf
.screens
[screen
].wiboxes
.len
; i
++)
786 wibox_t
*wibox
= globalconf
.screens
[screen
].wiboxes
.tab
[i
];
787 if(luaA_wibox_hasitem(L
, wibox
, item
))
789 /* recompute widget node list */
790 wibox_widgets_table_build(L
, wibox
);
791 lua_pop(L
, 1); /* remove widgets table */
796 for(client_t
*c
= globalconf
.clients
; c
; c
= c
->next
)
797 if(c
->titlebar
&& luaA_wibox_hasitem(L
, c
->titlebar
, item
))
799 /* recompute widget node list */
800 wibox_widgets_table_build(L
, c
->titlebar
);
801 lua_pop(L
, 1); /* remove widgets table */
806 * \param L The Lua VM state.
807 * \return The number of elements pushed on stack.
809 * \lfield screen Screen number.
810 * \lfield client The client attached to this titlebar.
811 * \lfield border_width Border width.
812 * \lfield border_color Border color.
813 * \lfield align The alignment.
814 * \lfield fg Foreground color.
815 * \lfield bg Background color.
816 * \lfield position The position.
817 * \lfield ontop On top of other windows.
818 * \lfield cursor The mouse cursor.
821 luaA_wibox_index(lua_State
*L
)
824 wibox_t
**wibox
= luaA_checkudata(L
, 1, "wibox");
825 const char *attr
= luaL_checklstring(L
, 2, &len
);
827 if(luaA_usemetatable(L
, 1, 2))
830 switch(a_tokenize(attr
, len
))
835 lua_pushboolean(L
, (*wibox
)->isvisible
);
838 if((c
= client_getbytitlebar(*wibox
)))
839 return luaA_client_userdata_new(L
, c
);
843 if((*wibox
)->screen
== SCREEN_UNDEF
)
845 lua_pushnumber(L
, (*wibox
)->screen
+ 1);
847 case A_TK_BORDER_WIDTH
:
848 lua_pushnumber(L
, (*wibox
)->sw
.border
.width
);
850 case A_TK_BORDER_COLOR
:
851 luaA_pushcolor(L
, &(*wibox
)->sw
.border
.color
);
854 lua_pushstring(L
, draw_align_tostr((*wibox
)->align
));
857 luaA_pushcolor(L
, &(*wibox
)->sw
.ctx
.fg
);
860 luaA_pushcolor(L
, &(*wibox
)->sw
.ctx
.bg
);
863 lua_pushstring(L
, position_tostr((*wibox
)->position
));
866 lua_pushboolean(L
, (*wibox
)->ontop
);
868 case A_TK_ORIENTATION
:
869 lua_pushstring(L
, orientation_tostr((*wibox
)->sw
.orientation
));
872 if((*wibox
)->widgets_table
!= LUA_REFNIL
)
873 lua_rawgeti(L
, LUA_REGISTRYINDEX
, (*wibox
)->widgets_table
);
878 lua_pushstring(L
, (*wibox
)->cursor
);
883 if ((d
= window_opacity_get((*wibox
)->sw
.window
)) >= 0)
884 lua_pushnumber(L
, d
);
896 /* Set or get the wibox geometry.
897 * \param L The Lua VM state.
898 * \return The number of elements pushed on stack.
900 * \lparam An optional table with wibox geometry.
901 * \lreturn The wibox geometry.
904 luaA_wibox_geometry(lua_State
*L
)
906 wibox_t
**wibox
= luaA_checkudata(L
, 1, "wibox");
908 if(lua_gettop(L
) == 2)
912 luaA_checktable(L
, 2);
913 wingeom
.x
= luaA_getopt_number(L
, 2, "x", (*wibox
)->sw
.geometry
.x
);
914 wingeom
.y
= luaA_getopt_number(L
, 2, "y", (*wibox
)->sw
.geometry
.y
);
915 wingeom
.width
= luaA_getopt_number(L
, 2, "width", (*wibox
)->sw
.geometry
.width
);
916 wingeom
.height
= luaA_getopt_number(L
, 2, "height", (*wibox
)->sw
.geometry
.height
);
918 switch((*wibox
)->type
)
920 case WIBOX_TYPE_TITLEBAR
:
921 wibox_resize(*wibox
, wingeom
.width
, wingeom
.height
);
923 case WIBOX_TYPE_NORMAL
:
924 if((*wibox
)->position
== Floating
)
925 wibox_moveresize(*wibox
, wingeom
);
926 else if(wingeom
.width
!= (*wibox
)->sw
.geometry
.width
927 || wingeom
.height
!= (*wibox
)->sw
.geometry
.height
)
929 wibox_resize(*wibox
, wingeom
.width
, wingeom
.height
);
930 globalconf
.screens
[(*wibox
)->screen
].need_arrange
= true;
936 return luaA_pusharea(L
, (*wibox
)->sw
.geometry
);
940 * \param L The Lua VM state.
941 * \return The number of elements pushed on stack.
944 luaA_wibox_newindex(lua_State
*L
)
947 wibox_t
**wibox
= luaA_checkudata(L
, 1, "wibox");
948 const char *buf
, *attr
= luaL_checklstring(L
, 2, &len
);
951 switch((tok
= a_tokenize(attr
, len
)))
956 if((buf
= luaL_checklstring(L
, 3, &len
)))
957 if(xcolor_init_reply(xcolor_init_unchecked(&(*wibox
)->sw
.ctx
.fg
, buf
, len
)))
958 (*wibox
)->need_update
= true;
961 if((buf
= luaL_checklstring(L
, 3, &len
)))
962 if(xcolor_init_reply(xcolor_init_unchecked(&(*wibox
)->sw
.ctx
.bg
, buf
, len
)))
963 (*wibox
)->need_update
= true;
966 buf
= luaL_checklstring(L
, 3, &len
);
967 (*wibox
)->align
= draw_align_fromstr(buf
, len
);
968 switch((*wibox
)->type
)
970 case WIBOX_TYPE_NORMAL
:
971 wibox_position_update(*wibox
);
973 case WIBOX_TYPE_TITLEBAR
:
974 titlebar_update_geometry(client_getbytitlebar(*wibox
));
979 switch((*wibox
)->type
)
981 case WIBOX_TYPE_TITLEBAR
:
982 return luaA_titlebar_newindex(L
, *wibox
, tok
);
983 case WIBOX_TYPE_NORMAL
:
984 if((buf
= luaL_checklstring(L
, 3, &len
)))
985 wibox_setposition(*wibox
, position_fromstr(buf
, len
));
992 titlebar_client_detach(client_getbytitlebar(*wibox
));
995 client_t
**c
= luaA_checkudata(L
, 3, "client");
996 titlebar_client_attach(*c
, *wibox
);
1000 if((buf
= luaL_checkstring(L
, 3)))
1002 uint16_t cursor_font
= xcursor_font_fromstr(buf
);
1005 xcb_cursor_t cursor
= xcursor_new(globalconf
.connection
, cursor_font
);
1006 p_delete(&(*wibox
)->cursor
);
1007 (*wibox
)->cursor
= a_strdup(buf
);
1008 simplewindow_cursor_set(&(*wibox
)->sw
, cursor
);
1015 wibox_detach(*wibox
);
1016 titlebar_client_detach(client_getbytitlebar(*wibox
));
1020 int screen
= luaL_checknumber(L
, 3) - 1;
1021 luaA_checkscreen(screen
);
1022 if(screen
!= (*wibox
)->screen
)
1024 titlebar_client_detach(client_getbytitlebar(*wibox
));
1025 wibox_attach(*wibox
, &globalconf
.screens
[screen
]);
1030 b
= luaA_checkboolean(L
, 3);
1031 if(b
!= (*wibox
)->ontop
)
1033 (*wibox
)->ontop
= b
;
1037 case A_TK_ORIENTATION
:
1038 if((buf
= luaL_checklstring(L
, 3, &len
)))
1040 simplewindow_orientation_set(&(*wibox
)->sw
, orientation_fromstr(buf
, len
));
1041 (*wibox
)->need_update
= true;
1042 (*wibox
)->mouse_over
= NULL
;
1045 case A_TK_BORDER_COLOR
:
1046 if((buf
= luaL_checklstring(L
, 3, &len
)))
1047 if(xcolor_init_reply(xcolor_init_unchecked(&(*wibox
)->sw
.border
.color
, buf
, len
)))
1048 if((*wibox
)->sw
.window
)
1049 simplewindow_border_color_set(&(*wibox
)->sw
, &(*wibox
)->sw
.border
.color
);
1052 b
= luaA_checkboolean(L
, 3);
1053 if(b
!= (*wibox
)->isvisible
)
1054 switch((*wibox
)->type
)
1056 case WIBOX_TYPE_NORMAL
:
1057 wibox_setvisible(*wibox
, b
);
1059 case WIBOX_TYPE_TITLEBAR
:
1060 titlebar_set_visible(*wibox
, b
);
1065 if(luaA_isloop(L
, 3))
1067 luaA_warn(L
, "table is looping, cannot use this as widget table");
1070 luaA_register(L
, 3, &(*wibox
)->widgets_table
);
1071 /* recompute widget node list */
1072 wibox_widgets_table_build(L
, *wibox
);
1073 luaA_table2wtable(L
);
1077 window_opacity_set((*wibox
)->sw
.window
, -1);
1080 double d
= luaL_checknumber(L
, 3);
1081 if(d
>= 0 && d
<= 1)
1082 window_opacity_set((*wibox
)->sw
.window
, d
);
1086 switch((*wibox
)->type
)
1088 case WIBOX_TYPE_TITLEBAR
:
1089 return luaA_titlebar_newindex(L
, *wibox
, tok
);
1090 case WIBOX_TYPE_NORMAL
:
1098 /** Get or set mouse buttons bindings to a wibox.
1099 * \param L The Lua VM state.
1102 * \lparam An array of mouse button bindings objects, or nothing.
1103 * \return The array of mouse button bindings objects of this wibox.
1106 luaA_wibox_buttons(lua_State
*L
)
1108 wibox_t
**wibox
= luaA_checkudata(L
, 1, "wibox");
1109 button_array_t
*buttons
= &(*wibox
)->buttons
;
1111 if(lua_gettop(L
) == 2)
1113 luaA_button_array_set(L
, 2, buttons
);
1117 return luaA_button_array_get(L
, buttons
);
1120 const struct luaL_reg awesome_wibox_methods
[] =
1122 { "__call", luaA_wibox_new
},
1125 const struct luaL_reg awesome_wibox_meta
[] =
1127 { "buttons", luaA_wibox_buttons
},
1128 { "geometry", luaA_wibox_geometry
},
1129 { "__index", luaA_wibox_index
},
1130 { "__newindex", luaA_wibox_newindex
},
1131 { "__gc", luaA_wibox_gc
},
1132 { "__eq", luaA_wibox_eq
},
1133 { "__tostring", luaA_wibox_tostring
},
1137 // vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80