代码拉取完成,页面将自动刷新
/*
* widgets/window.c - gtk window widget wrapper
*
* Copyright © 2010 Mason Larobina <mason.larobina@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifdef GDK_WINDOWING_X11
#include <gdk/gdkx.h>
#endif
#include <gdk/gdkkeysyms.h>
#include "luah.h"
#include "widgets/common.h"
typedef struct {
widget_t *widget;
GtkWindow *win;
GdkWindowState state;
guint id;
} window_data_t;
static int window_id_next = 0;
static widget_t *
luaH_checkwindow(lua_State *L, gint udx)
{
widget_t *w = luaH_checkwidget(L, udx);
if (w->info->tok != L_TK_WINDOW)
luaL_argerror(L, udx, "expected window widget");
return w;
}
#define luaH_checkwindata(L, udx) ((window_data_t*)(luaH_checkwindow(L, udx)->data))
static void
destroy_win_cb(GtkWidget* UNUSED(win), widget_t *w)
{
/* remove window from global windows list */
g_ptr_array_remove(globalconf.windows, w);
}
static gint
can_close_cb(GtkWidget* UNUSED(win), GdkEvent *UNUSED(event), widget_t *w)
{
lua_State *L = common.L;
luaH_object_push(L, w->ref);
gint ret = luaH_object_emit_signal(L, -1, "can-close", 0, 1);
gboolean keep_open = ret && !lua_toboolean(L, -1);
lua_pop(L, ret + 1);
return keep_open;
}
static gint
luaH_window_set_dark_mode(lua_State *L)
{
window_data_t *d = luaH_checkwindata(L, 1);
gboolean dark_mode = lua_toboolean(L, 2);
g_object_set(gtk_widget_get_settings(GTK_WIDGET(d->win)),
"gtk-application-prefer-dark-theme", dark_mode, NULL);
return 0;
}
static gint
luaH_window_set_default_size(lua_State *L)
{
window_data_t *d = luaH_checkwindata(L, 1);
gint width = (gint) luaL_checknumber(L, 2);
gint height = (gint) luaL_checknumber(L, 3);
gtk_window_set_default_size(d->win, width, height);
return 0;
}
static gint
luaH_window_index(lua_State *L, widget_t *w, luakit_token_t token)
{
window_data_t *d = w->data;
switch(token) {
LUAKIT_WIDGET_INDEX_COMMON(w)
LUAKIT_WIDGET_BIN_INDEX_COMMON(w)
LUAKIT_WIDGET_CONTAINER_INDEX_COMMON(w)
/* push window class methods */
PF_CASE(SET_DEFAULT_SIZE, luaH_window_set_default_size)
/* push string properties */
PS_CASE(TITLE, gtk_window_get_title(d->win))
/* push boolean properties */
PB_CASE(DECORATED, gtk_window_get_decorated(d->win))
PB_CASE(URGENCY_HINT, gtk_window_get_urgency_hint(d->win))
PB_CASE(FULLSCREEN, d->state & GDK_WINDOW_STATE_FULLSCREEN)
PB_CASE(MAXIMIZED, d->state & GDK_WINDOW_STATE_MAXIMIZED)
PF_CASE(SET_DARK_MODE, luaH_window_set_dark_mode)
/* push integer properties */
PN_CASE(ID, d->id)
# ifdef GDK_WINDOWING_X11
case L_TK_ROOT_WIN_XID:
lua_pushlightuserdata(L, GDK_WINDOW(
# if GTK_CHECK_VERSION(3,12,0)
gdk_screen_get_root_window(gtk_widget_get_screen(GTK_WIDGET(d->win)))
# else
gtk_widget_get_root_window(GTK_WIDGET(d->win))
# endif
));
return 1;
PD_CASE(WIN_XID, GDK_WINDOW(gtk_widget_get_window(GTK_WIDGET(d->win))));
# endif
case L_TK_SCREEN:
lua_pushlightuserdata(L, gtk_window_get_screen(d->win));
return 1;
default:
break;
}
return 0;
}
static gint
luaH_window_newindex(lua_State *L, widget_t *w, luakit_token_t token)
{
window_data_t *d = w->data;
switch(token) {
LUAKIT_WIDGET_NEWINDEX_COMMON(w)
LUAKIT_WIDGET_BIN_NEWINDEX_COMMON(w)
case L_TK_DECORATED:
gtk_window_set_decorated(d->win, luaH_checkboolean(L, 3));
break;
case L_TK_URGENCY_HINT:
gtk_window_set_urgency_hint(d->win, luaH_checkboolean(L, 3));
break;
case L_TK_TITLE:
gtk_window_set_title(d->win, luaL_checkstring(L, 3));
break;
case L_TK_ICON:
gtk_window_set_icon_from_file(d->win, luaL_checkstring(L, 3), NULL);
break;
case L_TK_SCREEN:
if (!lua_islightuserdata(L, 3))
luaL_argerror(L, 3, "expected GdkScreen lightuserdata");
gtk_window_set_screen(d->win, (GdkScreen*)lua_touserdata(L, 3));
gtk_window_present(d->win);
break;
case L_TK_FULLSCREEN:
if (luaH_checkboolean(L, 3))
gtk_window_fullscreen(d->win);
else
gtk_window_unfullscreen(d->win);
return 0;
case L_TK_MAXIMIZED:
if (luaH_checkboolean(L, 3))
gtk_window_maximize(d->win);
else
gtk_window_unmaximize(d->win);
return 0;
default:
return 0;
}
return luaH_object_property_signal(L, 1, token);
}
static gboolean
window_state_cb(GtkWidget* UNUSED(widget), GdkEventWindowState *ev, widget_t *w)
{
window_data_t *d = (window_data_t*)w->data;
d->state = ev->new_window_state;
lua_State *L = common.L;
luaH_object_push(L, w->ref);
if (ev->changed_mask & GDK_WINDOW_STATE_MAXIMIZED)
luaH_object_property_signal(L, -1, L_TK_MAXIMIZED);
if (ev->changed_mask & GDK_WINDOW_STATE_FULLSCREEN)
luaH_object_property_signal(L, -1, L_TK_FULLSCREEN);
lua_pop(L, 1);
return FALSE;
}
static void
window_destructor(widget_t *w)
{
g_slice_free(window_data_t, w->data);
}
widget_t *
widget_window(lua_State *UNUSED(L), widget_t *w, luakit_token_t UNUSED(token))
{
w->index = luaH_window_index;
w->newindex = luaH_window_newindex;
w->destructor = window_destructor;
/* create private window data struct */
window_data_t *d = g_slice_new0(window_data_t);
d->widget = w;
w->data = d;
/* create and setup window widget */
w->widget = gtk_window_new(GTK_WINDOW_TOPLEVEL);
d->win = GTK_WINDOW(w->widget);
gtk_window_set_default_size(d->win, 800, 600);
gtk_window_set_title(d->win, "luakit");
if (globalconf.application)
gtk_window_set_application(d->win, globalconf.application);
GdkGeometry hints;
hints.min_width = 1;
hints.min_height = 1;
gtk_window_set_geometry_hints(d->win, NULL, &hints, GDK_HINT_MIN_SIZE);
g_object_connect(G_OBJECT(w->widget),
"signal::destroy", G_CALLBACK(destroy_win_cb), w,
LUAKIT_WIDGET_SIGNAL_COMMON(w)
"signal::add", G_CALLBACK(add_cb), w,
"signal::delete-event", G_CALLBACK(can_close_cb), w,
"signal::key-press-event", G_CALLBACK(key_press_cb), w,
"signal::remove", G_CALLBACK(remove_cb), w,
"signal::window-state-event", G_CALLBACK(window_state_cb), w,
NULL);
d->id = ++window_id_next;
/* add to global windows list */
g_ptr_array_add(globalconf.windows, w);
return w;
}
// vim: ft=c:et:sw=4:ts=8:sts=4:tw=80
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。