~ubuntu-branches/ubuntu/utopic/cairo-dock/utopic

« back to all changes in this revision

Viewing changes to src/implementations/cairo-dock-kwin-integration.c

Tags: upstream-2.3.0~1
ImportĀ upstreamĀ versionĀ 2.3.0~1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/**
 
2
* This file is a part of the Cairo-Dock project
 
3
*
 
4
* Copyright : (C) see the 'copyright' file.
 
5
* E-mail    : see the 'copyright' file.
 
6
*
 
7
* This program is free software; you can redistribute it and/or
 
8
* modify it under the terms of the GNU General Public License
 
9
* as published by the Free Software Foundation; either version 3
 
10
* of the License, or (at your option) any later version.
 
11
*
 
12
* This program is distributed in the hope that it will be useful,
 
13
* but WITHOUT ANY WARRANTY; without even the implied warranty of
 
14
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
15
* GNU General Public License for more details.
 
16
* You should have received a copy of the GNU General Public License
 
17
* along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
18
*/
 
19
 
 
20
#include <gdk/gdkx.h>
 
21
 
 
22
#include "cairo-dock-icon-factory.h"
 
23
#include "cairo-dock-X-utilities.h"
 
24
#include "cairo-dock-log.h"
 
25
#include "cairo-dock-dbus.h"
 
26
#include "cairo-dock-icon-factory.h"
 
27
#include "cairo-dock-dock-factory.h"
 
28
#include "cairo-dock-X-manager.h"
 
29
#include "cairo-dock-X-utilities.h"
 
30
#include "cairo-dock-class-manager.h"
 
31
#include "cairo-dock-kwin-integration.h"
 
32
 
 
33
static DBusGProxy *s_pKwinAccelProxy = NULL;
 
34
static DBusGProxy *s_pPlasmaAccelProxy = NULL;
 
35
 
 
36
#define CD_KWIN_BUS "org.kde.kwin"
 
37
#define CD_KGLOBALACCEL_BUS "org.kde.kglobalaccel"
 
38
#define CD_KGLOBALACCEL_KWIN_OBJECT "/component/kwin"
 
39
#define CD_KGLOBALACCEL_PLASMA_OBJECT "/component/plasma_desktop"
 
40
#define CD_KGLOBALACCEL_INTERFACE "org.kde.kglobalaccel.Component"
 
41
 
 
42
 
 
43
static gboolean present_windows (void)
 
44
{
 
45
        gboolean bSuccess = FALSE;
 
46
        if (s_pKwinAccelProxy != NULL)
 
47
        {
 
48
                GError *erreur = NULL;
 
49
                bSuccess = dbus_g_proxy_call (s_pKwinAccelProxy, "invokeShortcut", &erreur,
 
50
                        G_TYPE_STRING, "ExposeAll",
 
51
                        G_TYPE_INVALID,
 
52
                        G_TYPE_INVALID);
 
53
                if (erreur)
 
54
                {
 
55
                        cd_warning ("Kwin ExposeAll error: %s", erreur->message);
 
56
                        g_error_free (erreur);
 
57
                        bSuccess = FALSE;
 
58
                }
 
59
        }
 
60
        return bSuccess;
 
61
}
 
62
 
 
63
static gboolean present_class (const gchar *cClass)
 
64
{
 
65
        cd_debug ("%s (%s)", __func__, cClass);
 
66
        GList *pIcons = (GList*)cairo_dock_list_existing_appli_with_class (cClass);
 
67
        if (pIcons == NULL)
 
68
                return FALSE;
 
69
        
 
70
        Atom aPresentWindows = XInternAtom (cairo_dock_get_Xdisplay(), "_KDE_PRESENT_WINDOWS_GROUP", False);
 
71
        Window *data = g_new0 (Window, g_list_length (pIcons));
 
72
        Icon *pOneIcon;
 
73
        GList *ic;
 
74
        int i = 0;
 
75
        for (ic = pIcons; ic != NULL; ic = ic->next)
 
76
        {
 
77
                pOneIcon = ic->data;
 
78
                data[i++] = pOneIcon->Xid;
 
79
        }
 
80
        XChangeProperty(cairo_dock_get_Xdisplay(), data[0], aPresentWindows, aPresentWindows, 32, PropModeReplace, (unsigned char *)data, i);
 
81
        g_free (data);
 
82
        return TRUE;
 
83
}
 
84
 
 
85
static gboolean present_desktops (void)
 
86
{
 
87
        gboolean bSuccess = FALSE;
 
88
        if (s_pKwinAccelProxy != NULL)
 
89
        {
 
90
                GError *erreur = NULL;
 
91
                bSuccess = dbus_g_proxy_call (s_pKwinAccelProxy, "invokeShortcut", &erreur,
 
92
                        G_TYPE_STRING, "ShowDesktopGrid",
 
93
                        G_TYPE_INVALID,
 
94
                        G_TYPE_INVALID);
 
95
                if (erreur)
 
96
                {
 
97
                        cd_warning ("Kwin ShowDesktopGrid error: %s", erreur->message);
 
98
                        g_error_free (erreur);
 
99
                        bSuccess = FALSE;
 
100
                }
 
101
        }
 
102
        return bSuccess;
 
103
}
 
104
 
 
105
static gboolean show_widget_layer (void)
 
106
{
 
107
        gboolean bSuccess = FALSE;
 
108
        if (s_pPlasmaAccelProxy != NULL)
 
109
        {
 
110
                GError *erreur = NULL;
 
111
                bSuccess = dbus_g_proxy_call (s_pPlasmaAccelProxy, "invokeShortcut", &erreur,
 
112
                        G_TYPE_STRING, "Show Dashboard",
 
113
                        G_TYPE_INVALID,
 
114
                        G_TYPE_INVALID);
 
115
                if (erreur)
 
116
                {
 
117
                        cd_warning ("Plasma-desktop 'Show Dashboard' error: %s", erreur->message);
 
118
                        g_error_free (erreur);
 
119
                        bSuccess = FALSE;
 
120
                }
 
121
        }
 
122
        return FALSE;
 
123
}
 
124
 
 
125
#define x_icon_geometry(icon, pDock) (pDock->container.iWindowPositionX + icon->fXAtRest + (pDock->container.iWidth - pDock->fFlatDockWidth) / 2 + (pDock->iOffsetForExtend * (pDock->fAlign - .5) * 2))
 
126
#define y_icon_geometry(icon, pDock) (pDock->container.iWindowPositionY + icon->fDrawY - icon->fHeight * myIconsParam.fAmplitude * pDock->fMagnitudeMax)
 
127
static void _set_one_icon_geometry_for_window_manager (Icon *icon, CairoDock *pDock)
 
128
{
 
129
        cd_debug ("%s (%s)", __func__, icon?icon->cName:"none");
 
130
        long data[1+6];
 
131
        if (icon != NULL)
 
132
        {
 
133
                data[0] = 1;  // 1 preview.
 
134
                data[1+0] = 5;  // 5 elements for the current preview: X id, x, y, w, h
 
135
                data[1+1] = icon->Xid;
 
136
                
 
137
                int iX, iY, iWidth, iHeight;
 
138
                iX = x_icon_geometry (icon, pDock);
 
139
                iY = y_icon_geometry (icon, pDock);  // il faudrait un fYAtRest ...
 
140
                iWidth = icon->fWidth;
 
141
                iHeight = icon->fHeight * (1. + 2*myIconsParam.fAmplitude * pDock->fMagnitudeMax);  // on elargit en haut et en bas, pour gerer les cas ou l'icone grossirait vers le haut ou vers le bas.
 
142
                
 
143
                if (pDock->container.bIsHorizontal)
 
144
                {
 
145
                        data[1+2] = iX;
 
146
                        data[1+3] = (pDock->container.bDirectionUp ? -50 - 200: 50 + 200);
 
147
                }
 
148
                else
 
149
                {
 
150
                        data[1+2] = iY;
 
151
                        data[1+3] = iX - 200/2;
 
152
                }
 
153
                data[1+4] = 200;
 
154
                data[1+5] = 200;
 
155
        }
 
156
        else
 
157
        {
 
158
                data[0] = 0;
 
159
                
 
160
        }
 
161
        
 
162
        Atom atom = XInternAtom (cairo_dock_get_Xdisplay(), "_KDE_WINDOW_PREVIEW", False);
 
163
        Window Xid = GDK_WINDOW_XID (pDock->container.pWidget->window);
 
164
        XChangeProperty (cairo_dock_get_Xdisplay(), Xid, atom, atom, 32, PropModeReplace, (const unsigned char*)data, 1+6);
 
165
}
 
166
static gboolean _on_enter_icon (gpointer pUserData, Icon *pIcon, CairoDock *pDock, gboolean *bStartAnimation)
 
167
{
 
168
        if (CAIRO_DOCK_IS_APPLI (pIcon))
 
169
        {
 
170
                _set_one_icon_geometry_for_window_manager (pIcon, pDock);
 
171
        }
 
172
        else
 
173
        {
 
174
                _set_one_icon_geometry_for_window_manager (NULL, pDock);
 
175
        }
 
176
        return CAIRO_DOCK_LET_PASS_NOTIFICATION;
 
177
}
 
178
 
 
179
static void _register_kwin_backend (void)
 
180
{
 
181
        CairoDockWMBackend *p = g_new0 (CairoDockWMBackend, 1);
 
182
        
 
183
        p->present_class = present_class;
 
184
        p->present_windows = present_windows;
 
185
        p->present_desktops = present_desktops;
 
186
        p->show_widget_layer = show_widget_layer;
 
187
        p->set_on_widget_layer = NULL;  // the Dashboard is not a real widget layer :-/
 
188
        
 
189
        cairo_dock_wm_register_backend (p);
 
190
        
 
191
        /*cairo_dock_register_notification_on_object (&myContainersMgr,
 
192
                NOTIFICATION_ENTER_ICON,
 
193
                (CairoDockNotificationFunc) _on_enter_icon,
 
194
                CAIRO_DOCK_RUN_FIRST, NULL);*/
 
195
}
 
196
 
 
197
static void _unregister_kwin_backend (void)
 
198
{
 
199
        cairo_dock_wm_register_backend (NULL);
 
200
        /*cairo_dock_remove_notification_func_on_object (&myContainersMgr,
 
201
                NOTIFICATION_ENTER_ICON,
 
202
                (CairoDockNotificationFunc) _on_enter_icon, NULL);*/
 
203
}
 
204
 
 
205
static void _on_kwin_owner_changed (gboolean bOwned, gpointer data)
 
206
{
 
207
        cd_debug ("Kwin is on the bus (%d)", bOwned);
 
208
        
 
209
        if (bOwned)  // set up the proxies
 
210
        {
 
211
                g_return_if_fail (s_pKwinAccelProxy == NULL);
 
212
                
 
213
                s_pKwinAccelProxy = cairo_dock_create_new_session_proxy (
 
214
                        CD_KGLOBALACCEL_BUS,
 
215
                        CD_KGLOBALACCEL_KWIN_OBJECT,
 
216
                        CD_KGLOBALACCEL_INTERFACE);
 
217
                
 
218
                s_pPlasmaAccelProxy = cairo_dock_create_new_session_proxy (
 
219
                        CD_KGLOBALACCEL_BUS,
 
220
                        CD_KGLOBALACCEL_PLASMA_OBJECT,
 
221
                        CD_KGLOBALACCEL_INTERFACE);
 
222
                
 
223
                _register_kwin_backend ();
 
224
        }
 
225
        else if (s_pKwinAccelProxy != NULL)
 
226
        {
 
227
                g_object_unref (s_pKwinAccelProxy);
 
228
                s_pKwinAccelProxy = NULL;
 
229
                
 
230
                _unregister_kwin_backend ();
 
231
        }
 
232
}
 
233
static void _on_detect_kwin (gboolean bPresent, gpointer data)
 
234
{
 
235
        cd_debug ("Kwin is present: %d", bPresent);
 
236
        if (bPresent)
 
237
        {
 
238
                _on_kwin_owner_changed (TRUE, NULL);
 
239
        }
 
240
        cairo_dock_watch_dbus_name_owner (CD_KWIN_BUS,
 
241
                (CairoDockDbusNameOwnerChangedFunc) _on_kwin_owner_changed,
 
242
                NULL);
 
243
}
 
244
void cd_init_kwin_backend (void)
 
245
{
 
246
        DBusGProxyCall *call = cairo_dock_dbus_detect_application_async (CD_KWIN_BUS,
 
247
                (CairoDockOnAppliPresentOnDbus) _on_detect_kwin,
 
248
                NULL);
 
249
}