mirror of
https://github.com/awesomeWM/awesome
synced 2024-11-17 07:47:41 +01:00
ec076ca4bd
The XEmbed protocol defines a special property that defines if the embedded window wants to be visible or not. Up to now, awesome always ignored this entry and instead behaved as if the bit was set. This commit makes it properly respect the bit. Testing done: None. No idea how. Apparently nothing really uses this bit, because we didn't get bug reports about it yet. Signed-off-by: Uli Schlachter <psychon@znc.in>
151 lines
4.5 KiB
C
151 lines
4.5 KiB
C
/*
|
|
* common/xembed.c - XEMBED functions
|
|
*
|
|
* Copyright © 2007-2008 Julien Danjou <julien@danjou.info>
|
|
* Copyright © 2004 Matthew Reppert
|
|
*
|
|
* 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 2 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, write to the Free Software Foundation, Inc.,
|
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
*
|
|
*/
|
|
|
|
#include "common/xembed.h"
|
|
#include "common/util.h"
|
|
#include "common/atoms.h"
|
|
|
|
/* I should really include the correct header instead... */
|
|
void luaA_systray_invalidate(void);
|
|
|
|
/** Send an XEMBED message to a window.
|
|
* \param connection Connection to the X server.
|
|
* \param towin Destination window
|
|
* \param message The message.
|
|
* \param d1 Element 3 of message.
|
|
* \param d2 Element 4 of message.
|
|
* \param d3 Element 5 of message.
|
|
*/
|
|
void
|
|
xembed_message_send(xcb_connection_t *connection, xcb_window_t towin,
|
|
long message, long d1, long d2, long d3)
|
|
{
|
|
xcb_client_message_event_t ev;
|
|
|
|
p_clear(&ev, 1);
|
|
ev.response_type = XCB_CLIENT_MESSAGE;
|
|
ev.window = towin;
|
|
ev.format = 32;
|
|
ev.data.data32[0] = XCB_CURRENT_TIME;
|
|
ev.data.data32[1] = message;
|
|
ev.data.data32[2] = d1;
|
|
ev.data.data32[3] = d2;
|
|
ev.data.data32[4] = d3;
|
|
ev.type = _XEMBED;
|
|
xcb_send_event(connection, false, towin, XCB_EVENT_MASK_NO_EVENT, (char *) &ev);
|
|
}
|
|
|
|
/** Deliver a request to get XEMBED info for a window.
|
|
* \param connection The X connection.
|
|
* \param win The window.
|
|
* \return A cookie.
|
|
*/
|
|
xcb_get_property_cookie_t
|
|
xembed_info_get_unchecked(xcb_connection_t *connection, xcb_window_t win)
|
|
{
|
|
return xcb_get_property_unchecked(connection, false, win, _XEMBED_INFO,
|
|
XCB_GET_PROPERTY_TYPE_ANY, 0L, 2);
|
|
}
|
|
|
|
static bool
|
|
xembed_info_from_reply(xembed_info_t *info, xcb_get_property_reply_t *prop_r)
|
|
{
|
|
uint32_t *data;
|
|
|
|
if(!prop_r || !prop_r->value_len)
|
|
return false;
|
|
|
|
if(!(data = (uint32_t *) xcb_get_property_value(prop_r)))
|
|
return false;
|
|
|
|
info->version = data[0];
|
|
info->flags = data[1] & XEMBED_INFO_FLAGS_ALL;
|
|
|
|
return true;
|
|
}
|
|
|
|
/** Get the XEMBED info for a window.
|
|
* \param connection The X connection.
|
|
* \param cookie The cookie of the request.
|
|
* \param info The xembed_info_t structure to fill.
|
|
*/
|
|
bool
|
|
xembed_info_get_reply(xcb_connection_t *connection,
|
|
xcb_get_property_cookie_t cookie,
|
|
xembed_info_t *info)
|
|
{
|
|
xcb_get_property_reply_t *prop_r = xcb_get_property_reply(connection, cookie, NULL);
|
|
bool ret = xembed_info_from_reply(info, prop_r);
|
|
p_delete(&prop_r);
|
|
return ret;
|
|
}
|
|
|
|
/** Get a XEMBED window from a xembed_window_t list.
|
|
* \param list The xembed window list.
|
|
* \param win The window to look for.
|
|
* \return The xembed window if found, NULL otherwise.
|
|
*/
|
|
xembed_window_t *
|
|
xembed_getbywin(xembed_window_array_t *list, xcb_window_t win)
|
|
{
|
|
for(int i = 0; i < list->len; i++)
|
|
if(list->tab[i].win == win)
|
|
return &list->tab[i];
|
|
return NULL;
|
|
}
|
|
|
|
/** Update embedded window properties.
|
|
* \param connection The X connection.
|
|
* \param emwin The embedded window.
|
|
*/
|
|
void
|
|
xembed_property_update(xcb_connection_t *connection, xembed_window_t *emwin,
|
|
xcb_get_property_reply_t *reply)
|
|
{
|
|
int flags_changed;
|
|
xembed_info_t info = { 0, 0 };
|
|
|
|
xembed_info_from_reply(&info, reply);
|
|
|
|
/* test if it changed */
|
|
if(!(flags_changed = info.flags ^ emwin->info.flags))
|
|
return;
|
|
|
|
emwin->info.flags = info.flags;
|
|
if(flags_changed & XEMBED_MAPPED)
|
|
{
|
|
if(info.flags & XEMBED_MAPPED)
|
|
{
|
|
xcb_map_window(connection, emwin->win);
|
|
xembed_window_activate(connection, emwin->win);
|
|
}
|
|
else
|
|
{
|
|
xcb_unmap_window(connection, emwin->win);
|
|
xembed_window_deactivate(connection, emwin->win);
|
|
xembed_focus_out(connection, emwin->win);
|
|
}
|
|
luaA_systray_invalidate();
|
|
}
|
|
}
|
|
|
|
// vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:textwidth=80
|