1 /*
2 * live-window-simple: An actor showing the content of a window which will
3 * be updated if changed and visible on active workspace.
4 *
5 * Copyright 2012-2020 Stephan Haller <nomad@froevel.de>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (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 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
20 * MA 02110-1301, USA.
21 *
22 *
23 */
24
25 #ifdef HAVE_CONFIG_H
26 #include "config.h"
27 #endif
28
29 #include <libxfdashboard/live-window-simple.h>
30
31 #include <glib/gi18n-lib.h>
32
33 #include <libxfdashboard/click-action.h>
34 #include <libxfdashboard/window-content.h>
35 #include <libxfdashboard/image-content.h>
36 #include <libxfdashboard/stylable.h>
37 #include <libxfdashboard/enums.h>
38 #include <libxfdashboard/compat.h>
39 #include <libxfdashboard/debug.h>
40
41
42 /* Define this class in GObject system */
43 struct _XfdashboardLiveWindowSimplePrivate
44 {
45 /* Properties related */
46 XfdashboardWindowTrackerWindow *window;
47 XfdashboardLiveWindowSimpleDisplayType displayType;
48
49 /* Instance related */
50 gboolean isVisible;
51 ClutterActor *actorWindow;
52 gboolean destroyOnClose;
53 };
54
55 G_DEFINE_TYPE_WITH_PRIVATE(XfdashboardLiveWindowSimple,
56 xfdashboard_live_window_simple,
57 XFDASHBOARD_TYPE_BACKGROUND)
58
59 /* Properties */
60 enum
61 {
62 PROP_0,
63
64 PROP_WINDOW,
65 PROP_DISPLAY_TYPE,
66 PROP_DESTROY_ON_CLOSE,
67
68 PROP_LAST
69 };
70
71 static GParamSpec* XfdashboardLiveWindowSimpleProperties[PROP_LAST]={ 0, };
72
73 /* Signals */
74 enum
75 {
76 SIGNAL_GEOMETRY_CHANGED,
77 SIGNAL_VISIBILITY_CHANGED,
78 SIGNAL_WORKSPACE_CHANGED,
79
80 SIGNAL_LAST
81 };
82
83 static guint XfdashboardLiveWindowSimpleSignals[SIGNAL_LAST]={ 0, };
84
85 /* IMPLEMENTATION: Private variables and methods */
86
87 /* Check if window should be shown */
_xfdashboard_live_window_simple_is_visible_window(XfdashboardLiveWindowSimple * self,XfdashboardWindowTrackerWindow * inWindow)88 static gboolean _xfdashboard_live_window_simple_is_visible_window(XfdashboardLiveWindowSimple *self, XfdashboardWindowTrackerWindow *inWindow)
89 {
90 XfdashboardWindowTrackerWindowState state;
91
92 g_return_val_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_WINDOW(inWindow), FALSE);
93
94 /* Determine if windows should be shown depending on its state */
95 state=xfdashboard_window_tracker_window_get_state(inWindow);
96 if((state & XFDASHBOARD_WINDOW_TRACKER_WINDOW_STATE_SKIP_PAGER) ||
97 (state & XFDASHBOARD_WINDOW_TRACKER_WINDOW_STATE_SKIP_TASKLIST))
98 {
99 return(FALSE);
100 }
101
102 /* If we get here the window should be shown */
103 return(TRUE);
104 }
105
106 /* Position and/or size of window has changed */
_xfdashboard_live_window_simple_on_geometry_changed(XfdashboardLiveWindowSimple * self,gpointer inUserData)107 static void _xfdashboard_live_window_simple_on_geometry_changed(XfdashboardLiveWindowSimple *self,
108 gpointer inUserData)
109 {
110 XfdashboardLiveWindowSimplePrivate *priv;
111 XfdashboardWindowTrackerWindow *window;
112
113 g_return_if_fail(XFDASHBOARD_IS_LIVE_WINDOW_SIMPLE(self));
114 g_return_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_WINDOW(inUserData));
115
116 priv=self->priv;
117 window=XFDASHBOARD_WINDOW_TRACKER_WINDOW(inUserData);
118
119 /* Check if signal is for this window */
120 if(window!=priv->window) return;
121
122 /* Actor's allocation may change because of new geometry so relayout */
123 clutter_actor_queue_relayout(CLUTTER_ACTOR(self));
124
125 /* Emit "geometry-changed" signal */
126 g_signal_emit(self, XfdashboardLiveWindowSimpleSignals[SIGNAL_GEOMETRY_CHANGED], 0);
127 }
128
129 /* Window's state has changed */
_xfdashboard_live_window_simple_on_state_changed(XfdashboardLiveWindowSimple * self,XfdashboardWindowTrackerWindowState inOldState,gpointer inUserData)130 static void _xfdashboard_live_window_simple_on_state_changed(XfdashboardLiveWindowSimple *self,
131 XfdashboardWindowTrackerWindowState inOldState,
132 gpointer inUserData)
133 {
134 XfdashboardLiveWindowSimplePrivate *priv;
135 XfdashboardWindowTrackerWindow *window;
136 gboolean isVisible;
137 XfdashboardWindowTrackerWindowState state;
138
139 g_return_if_fail(XFDASHBOARD_IS_LIVE_WINDOW_SIMPLE(self));
140 g_return_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_WINDOW(inUserData));
141
142 priv=self->priv;
143 window=XFDASHBOARD_WINDOW_TRACKER_WINDOW(inUserData);
144
145 /* Check if signal is for this window */
146 if(window!=priv->window) return;
147
148 /* Check if window's visibility has changed */
149 isVisible=_xfdashboard_live_window_simple_is_visible_window(self, window);
150 if(priv->isVisible!=isVisible)
151 {
152 priv->isVisible=isVisible;
153 g_signal_emit(self, XfdashboardLiveWindowSimpleSignals[SIGNAL_VISIBILITY_CHANGED], 0);
154 }
155
156 /* Add or remove class depending on 'pinned' window state */
157 state=xfdashboard_window_tracker_window_get_state(window);
158 if(state & XFDASHBOARD_WINDOW_TRACKER_WINDOW_STATE_PINNED)
159 {
160 xfdashboard_stylable_add_class(XFDASHBOARD_STYLABLE(self), "window-state-pinned");
161 }
162 else
163 {
164 xfdashboard_stylable_remove_class(XFDASHBOARD_STYLABLE(self), "window-state-pinned");
165 }
166
167 /* Add or remove class depending on 'minimized' window state */
168 if(state & XFDASHBOARD_WINDOW_TRACKER_WINDOW_STATE_MINIMIZED)
169 {
170 xfdashboard_stylable_add_class(XFDASHBOARD_STYLABLE(self), "window-state-minimized");
171 }
172 else
173 {
174 xfdashboard_stylable_remove_class(XFDASHBOARD_STYLABLE(self), "window-state-minimized");
175 }
176
177 /* Add or remove class depending on 'maximized' window state */
178 if(state & XFDASHBOARD_WINDOW_TRACKER_WINDOW_STATE_MAXIMIZED)
179 {
180 xfdashboard_stylable_add_class(XFDASHBOARD_STYLABLE(self), "window-state-maximized");
181 }
182 else
183 {
184 xfdashboard_stylable_remove_class(XFDASHBOARD_STYLABLE(self), "window-state-maximized");
185 }
186
187 /* Add or remove class depending on 'urgent' window state */
188 if(state & XFDASHBOARD_WINDOW_TRACKER_WINDOW_STATE_URGENT)
189 {
190 xfdashboard_stylable_add_class(XFDASHBOARD_STYLABLE(self), "window-state-urgent");
191 }
192 else
193 {
194 xfdashboard_stylable_remove_class(XFDASHBOARD_STYLABLE(self), "window-state-urgent");
195 }
196 }
197
198 /* Window's workspace has changed */
_xfdashboard_live_window_simple_on_workspace_changed(XfdashboardLiveWindowSimple * self,XfdashboardWindowTrackerWorkspace * inWorkspace,gpointer inUserData)199 static void _xfdashboard_live_window_simple_on_workspace_changed(XfdashboardLiveWindowSimple *self,
200 XfdashboardWindowTrackerWorkspace *inWorkspace,
201 gpointer inUserData)
202 {
203 XfdashboardLiveWindowSimplePrivate *priv;
204 XfdashboardWindowTrackerWindow *window;
205
206 g_return_if_fail(XFDASHBOARD_IS_LIVE_WINDOW_SIMPLE(self));
207 g_return_if_fail(!inWorkspace || XFDASHBOARD_IS_WINDOW_TRACKER_WORKSPACE(inWorkspace));
208 g_return_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_WINDOW(inUserData));
209
210 priv=self->priv;
211 window=XFDASHBOARD_WINDOW_TRACKER_WINDOW(inUserData);
212
213 /* Check if signal is for this window */
214 if(window!=priv->window) return;
215
216 /* Emit "workspace-changed" signal */
217 g_signal_emit(self, XfdashboardLiveWindowSimpleSignals[SIGNAL_WORKSPACE_CHANGED], 0);
218 }
219
220 /* Window's was closed */
_xfdashboard_live_window_simple_on_closed(XfdashboardLiveWindowSimple * self,gpointer inUserData)221 static void _xfdashboard_live_window_simple_on_closed(XfdashboardLiveWindowSimple *self,
222 gpointer inUserData)
223 {
224 XfdashboardLiveWindowSimplePrivate *priv;
225 XfdashboardWindowTrackerWindow *window;
226
227 g_return_if_fail(XFDASHBOARD_IS_LIVE_WINDOW_SIMPLE(self));
228 g_return_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_WINDOW(inUserData));
229
230 priv=self->priv;
231 window=XFDASHBOARD_WINDOW_TRACKER_WINDOW(inUserData);
232
233 /* Check if signal is for this window */
234 if(window!=priv->window) return;
235
236 /* Check if actor should be destroy when window was closed */
237 if(priv->destroyOnClose)
238 {
239 XFDASHBOARD_DEBUG(self, WINDOWS,
240 "Window '%s' was closed and auto-destruction of actor was requested",
241 xfdashboard_window_tracker_window_get_name(priv->window));
242
243 if(xfdashboard_actor_destroy(CLUTTER_ACTOR(self)))
244 {
245 /* Release allocated resources early, before the dispose function
246 * is called, if an animation was started as the window is now gone!
247 */
248 if(priv->window)
249 {
250 g_signal_handlers_disconnect_by_data(priv->window, self);
251 priv->window=NULL;
252 }
253 }
254 }
255 }
256
257 /* Set up actor's content depending on display. If no window is set the current
258 * content of this actor is destroyed and a new one is not set up. The actor will
259 * be displayed empty.
260 */
_xfdashboard_live_window_simple_setup_content(XfdashboardLiveWindowSimple * self)261 static void _xfdashboard_live_window_simple_setup_content(XfdashboardLiveWindowSimple *self)
262 {
263 XfdashboardLiveWindowSimplePrivate *priv;
264 ClutterContent *content;
265
266 g_return_if_fail(XFDASHBOARD_IS_LIVE_WINDOW_SIMPLE(self));
267
268 priv=self->priv;
269
270 /* Destroy old actor's content */
271 clutter_actor_set_content(priv->actorWindow, NULL);
272
273 /* If no window is set we cannot set up actor's content but only destroy the
274 * old. So return here if no window is set.
275 */
276 if(!priv->window) return;
277
278 /* Setup actor's content depending on display type */
279 switch(priv->displayType)
280 {
281 case XFDASHBOARD_LIVE_WINDOW_SIMPLE_DISPLAY_TYPE_LIVE_PREVIEW:
282 content=xfdashboard_window_tracker_window_get_content(priv->window);
283 clutter_actor_set_content(priv->actorWindow, content);
284 g_object_unref(content);
285 break;
286
287 case XFDASHBOARD_LIVE_WINDOW_SIMPLE_DISPLAY_TYPE_ICON:
288 content=xfdashboard_image_content_new_for_pixbuf(xfdashboard_window_tracker_window_get_icon(priv->window));
289 clutter_actor_set_content(priv->actorWindow, content);
290 g_object_unref(content);
291 break;
292
293 default:
294 g_assert_not_reached();
295 break;
296 }
297 }
298
299 /* IMPLEMENTATION: ClutterActor */
300
301 /* Get preferred width/height */
_xfdashboard_live_window_simple_get_preferred_height(ClutterActor * self,gfloat inForWidth,gfloat * outMinHeight,gfloat * outNaturalHeight)302 static void _xfdashboard_live_window_simple_get_preferred_height(ClutterActor *self,
303 gfloat inForWidth,
304 gfloat *outMinHeight,
305 gfloat *outNaturalHeight)
306 {
307 XfdashboardLiveWindowSimplePrivate *priv=XFDASHBOARD_LIVE_WINDOW_SIMPLE(self)->priv;
308 gfloat minHeight, naturalHeight;
309
310 minHeight=naturalHeight=0.0f;
311
312 /* Determine size of window if available and visible (should usually be the largest actor) */
313 if(priv->actorWindow &&
314 clutter_actor_is_visible(priv->actorWindow) &&
315 priv->window)
316 {
317 gint windowHeight;
318
319 xfdashboard_window_tracker_window_get_geometry(priv->window, NULL, NULL, NULL, &windowHeight);
320 if(windowHeight<=0.0)
321 {
322 ClutterContent *content;
323 gfloat childNaturalHeight;
324
325 /* If we get here getting window size failed so fallback to old
326 * behaviour by getting size of window content associated to actor.
327 */
328 content=clutter_actor_get_content(priv->actorWindow);
329 if(content &&
330 XFDASHBOARD_IS_WINDOW_CONTENT(content))
331 {
332 if(clutter_content_get_preferred_size(content, NULL, &childNaturalHeight)) windowHeight=childNaturalHeight;
333 XFDASHBOARD_DEBUG(self, WINDOWS,
334 "Using fallback method to determine preferred height for window '%s'",
335 xfdashboard_window_tracker_window_get_name(priv->window));
336 }
337 }
338
339 if(windowHeight>minHeight) minHeight=windowHeight;
340 if(windowHeight>naturalHeight) naturalHeight=windowHeight;
341 }
342
343 /* Store sizes computed */
344 if(outMinHeight) *outMinHeight=minHeight;
345 if(outNaturalHeight) *outNaturalHeight=naturalHeight;
346 }
347
_xfdashboard_live_window_simple_get_preferred_width(ClutterActor * self,gfloat inForHeight,gfloat * outMinWidth,gfloat * outNaturalWidth)348 static void _xfdashboard_live_window_simple_get_preferred_width(ClutterActor *self,
349 gfloat inForHeight,
350 gfloat *outMinWidth,
351 gfloat *outNaturalWidth)
352 {
353 XfdashboardLiveWindowSimplePrivate *priv=XFDASHBOARD_LIVE_WINDOW_SIMPLE(self)->priv;
354 gfloat minWidth, naturalWidth;
355
356 minWidth=naturalWidth=0.0f;
357
358 /* Determine size of window if available and visible (should usually be the largest actor) */
359 if(priv->actorWindow &&
360 clutter_actor_is_visible(priv->actorWindow) &&
361 priv->window)
362 {
363 gint windowWidth;
364
365 xfdashboard_window_tracker_window_get_geometry(priv->window, NULL, NULL, &windowWidth, NULL);
366 if(windowWidth<=0.0)
367 {
368 ClutterContent *content;
369 gfloat childNaturalWidth;
370
371 /* If we get here getting window size failed so fallback to old
372 * behaviour by getting size of window content associated to actor.
373 */
374 content=clutter_actor_get_content(priv->actorWindow);
375 if(content &&
376 XFDASHBOARD_IS_WINDOW_CONTENT(content))
377 {
378 if(clutter_content_get_preferred_size(content, &childNaturalWidth, NULL)) windowWidth=childNaturalWidth;
379 XFDASHBOARD_DEBUG(self, WINDOWS,
380 "Using fallback method to determine preferred width for window '%s'",
381 xfdashboard_window_tracker_window_get_name(priv->window));
382 }
383 }
384
385 if(windowWidth>minWidth) minWidth=windowWidth;
386 if(windowWidth>naturalWidth) naturalWidth=windowWidth;
387 }
388
389 /* Store sizes computed */
390 if(outMinWidth) *outMinWidth=minWidth;
391 if(outNaturalWidth) *outNaturalWidth=naturalWidth;
392 }
393
394 /* Allocate position and size of actor and its children */
_xfdashboard_live_window_simple_allocate(ClutterActor * self,const ClutterActorBox * inBox,ClutterAllocationFlags inFlags)395 static void _xfdashboard_live_window_simple_allocate(ClutterActor *self,
396 const ClutterActorBox *inBox,
397 ClutterAllocationFlags inFlags)
398 {
399 XfdashboardLiveWindowSimplePrivate *priv=XFDASHBOARD_LIVE_WINDOW_SIMPLE(self)->priv;
400 ClutterActorBox *boxActorWindow=NULL;
401
402 /* Chain up to store the allocation of the actor */
403 CLUTTER_ACTOR_CLASS(xfdashboard_live_window_simple_parent_class)->allocate(self, inBox, inFlags);
404
405 /* Set allocation on window texture */
406 boxActorWindow=clutter_actor_box_copy(inBox);
407 clutter_actor_box_set_origin(boxActorWindow, 0.0f, 0.0f);
408 clutter_actor_allocate(priv->actorWindow, boxActorWindow, inFlags);
409
410 /* Release allocated resources */
411 if(boxActorWindow) clutter_actor_box_free(boxActorWindow);
412 }
413
414 /* IMPLEMENTATION: GObject */
415
416 /* Dispose this object */
_xfdashboard_live_window_simple_dispose(GObject * inObject)417 static void _xfdashboard_live_window_simple_dispose(GObject *inObject)
418 {
419 XfdashboardLiveWindowSimple *self=XFDASHBOARD_LIVE_WINDOW_SIMPLE(inObject);
420 XfdashboardLiveWindowSimplePrivate *priv=self->priv;
421
422 /* Dispose allocated resources */
423 if(priv->window)
424 {
425 g_signal_handlers_disconnect_by_data(priv->window, self);
426 priv->window=NULL;
427 }
428
429 if(priv->actorWindow)
430 {
431 clutter_actor_destroy(priv->actorWindow);
432 priv->actorWindow=NULL;
433 }
434
435 /* Call parent's class dispose method */
436 G_OBJECT_CLASS(xfdashboard_live_window_simple_parent_class)->dispose(inObject);
437 }
438
439 /* Set/get properties */
_xfdashboard_live_window_simple_set_property(GObject * inObject,guint inPropID,const GValue * inValue,GParamSpec * inSpec)440 static void _xfdashboard_live_window_simple_set_property(GObject *inObject,
441 guint inPropID,
442 const GValue *inValue,
443 GParamSpec *inSpec)
444 {
445 XfdashboardLiveWindowSimple *self=XFDASHBOARD_LIVE_WINDOW_SIMPLE(inObject);
446
447 switch(inPropID)
448 {
449 case PROP_WINDOW:
450 xfdashboard_live_window_simple_set_window(self, g_value_get_object(inValue));
451 break;
452
453 case PROP_DISPLAY_TYPE:
454 xfdashboard_live_window_simple_set_display_type(self, g_value_get_enum(inValue));
455 break;
456
457 case PROP_DESTROY_ON_CLOSE:
458 xfdashboard_live_window_simple_set_destroy_on_close(self, g_value_get_boolean(inValue));
459 break;
460
461 default:
462 G_OBJECT_WARN_INVALID_PROPERTY_ID(inObject, inPropID, inSpec);
463 break;
464 }
465 }
466
_xfdashboard_live_window_simple_get_property(GObject * inObject,guint inPropID,GValue * outValue,GParamSpec * inSpec)467 static void _xfdashboard_live_window_simple_get_property(GObject *inObject,
468 guint inPropID,
469 GValue *outValue,
470 GParamSpec *inSpec)
471 {
472 XfdashboardLiveWindowSimple *self=XFDASHBOARD_LIVE_WINDOW_SIMPLE(inObject);
473
474 switch(inPropID)
475 {
476 case PROP_WINDOW:
477 g_value_set_object(outValue, self->priv->window);
478 break;
479
480 case PROP_DISPLAY_TYPE:
481 g_value_set_enum(outValue, self->priv->displayType);
482 break;
483
484 case PROP_DESTROY_ON_CLOSE:
485 g_value_set_boolean(outValue, self->priv->destroyOnClose);
486 break;
487
488 default:
489 G_OBJECT_WARN_INVALID_PROPERTY_ID(inObject, inPropID, inSpec);
490 break;
491 }
492 }
493
494 /* Class initialization
495 * Override functions in parent classes and define properties
496 * and signals
497 */
xfdashboard_live_window_simple_class_init(XfdashboardLiveWindowSimpleClass * klass)498 static void xfdashboard_live_window_simple_class_init(XfdashboardLiveWindowSimpleClass *klass)
499 {
500 XfdashboardActorClass *actorClass=XFDASHBOARD_ACTOR_CLASS(klass);
501 ClutterActorClass *clutterActorClass=CLUTTER_ACTOR_CLASS(klass);
502 GObjectClass *gobjectClass=G_OBJECT_CLASS(klass);
503
504 /* Override functions */
505 clutterActorClass->get_preferred_width=_xfdashboard_live_window_simple_get_preferred_width;
506 clutterActorClass->get_preferred_height=_xfdashboard_live_window_simple_get_preferred_height;
507 clutterActorClass->allocate=_xfdashboard_live_window_simple_allocate;
508
509 gobjectClass->dispose=_xfdashboard_live_window_simple_dispose;
510 gobjectClass->set_property=_xfdashboard_live_window_simple_set_property;
511 gobjectClass->get_property=_xfdashboard_live_window_simple_get_property;
512
513 /* Define properties */
514 XfdashboardLiveWindowSimpleProperties[PROP_WINDOW]=
515 g_param_spec_object("window",
516 "Window",
517 "The window to show",
518 XFDASHBOARD_TYPE_WINDOW_TRACKER_WINDOW,
519 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
520
521 XfdashboardLiveWindowSimpleProperties[PROP_DISPLAY_TYPE]=
522 g_param_spec_enum("display-type",
523 "Display type",
524 "How to display the window",
525 XFDASHBOARD_TYPE_LIVE_WINDOW_SIMPLE_DISPLAY_TYPE,
526 XFDASHBOARD_LIVE_WINDOW_SIMPLE_DISPLAY_TYPE_LIVE_PREVIEW,
527 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
528
529 XfdashboardLiveWindowSimpleProperties[PROP_DESTROY_ON_CLOSE]=
530 g_param_spec_boolean("destroy-on-close",
531 "Destroy on close",
532 "If this actor should be destroy when window was closed",
533 TRUE,
534 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
535
536 g_object_class_install_properties(gobjectClass, PROP_LAST, XfdashboardLiveWindowSimpleProperties);
537
538 /* Define stylable properties */
539 xfdashboard_actor_install_stylable_property(actorClass, XfdashboardLiveWindowSimpleProperties[PROP_DISPLAY_TYPE]);
540
541 /* Define signals */
542 XfdashboardLiveWindowSimpleSignals[SIGNAL_GEOMETRY_CHANGED]=
543 g_signal_new("geometry-changed",
544 G_TYPE_FROM_CLASS(klass),
545 G_SIGNAL_RUN_LAST,
546 G_STRUCT_OFFSET(XfdashboardLiveWindowSimpleClass, geometry_changed),
547 NULL,
548 NULL,
549 g_cclosure_marshal_VOID__VOID,
550 G_TYPE_NONE,
551 0);
552
553 XfdashboardLiveWindowSimpleSignals[SIGNAL_VISIBILITY_CHANGED]=
554 g_signal_new("visibility-changed",
555 G_TYPE_FROM_CLASS(klass),
556 G_SIGNAL_RUN_LAST,
557 G_STRUCT_OFFSET(XfdashboardLiveWindowSimpleClass, visibility_changed),
558 NULL,
559 NULL,
560 g_cclosure_marshal_VOID__BOOLEAN,
561 G_TYPE_NONE,
562 1,
563 G_TYPE_BOOLEAN);
564
565 XfdashboardLiveWindowSimpleSignals[SIGNAL_WORKSPACE_CHANGED]=
566 g_signal_new("workspace-changed",
567 G_TYPE_FROM_CLASS(klass),
568 G_SIGNAL_RUN_LAST,
569 G_STRUCT_OFFSET(XfdashboardLiveWindowSimpleClass, workspace_changed),
570 NULL,
571 NULL,
572 g_cclosure_marshal_VOID__VOID,
573 G_TYPE_NONE,
574 0);
575 }
576
577 /* Object initialization
578 * Create private structure and set up default values
579 */
xfdashboard_live_window_simple_init(XfdashboardLiveWindowSimple * self)580 static void xfdashboard_live_window_simple_init(XfdashboardLiveWindowSimple *self)
581 {
582 XfdashboardLiveWindowSimplePrivate *priv;
583
584 priv=self->priv=xfdashboard_live_window_simple_get_instance_private(self);
585
586 /* This actor reacts on events */
587 clutter_actor_set_reactive(CLUTTER_ACTOR(self), TRUE);
588
589 /* Set default values */
590 priv->window=NULL;
591 priv->displayType=XFDASHBOARD_LIVE_WINDOW_SIMPLE_DISPLAY_TYPE_LIVE_PREVIEW;
592 priv->destroyOnClose=TRUE;
593
594
595 /* Set up child actors (order is important) */
596 priv->actorWindow=clutter_actor_new();
597 clutter_actor_show(priv->actorWindow);
598 clutter_actor_add_child(CLUTTER_ACTOR(self), priv->actorWindow);
599 }
600
601 /* IMPLEMENTATION: Public API */
602
603 /* Create new instance */
xfdashboard_live_window_simple_new(void)604 ClutterActor* xfdashboard_live_window_simple_new(void)
605 {
606 return(CLUTTER_ACTOR(g_object_new(XFDASHBOARD_TYPE_LIVE_WINDOW_SIMPLE, NULL)));
607 }
608
xfdashboard_live_window_simple_new_for_window(XfdashboardWindowTrackerWindow * inWindow)609 ClutterActor* xfdashboard_live_window_simple_new_for_window(XfdashboardWindowTrackerWindow *inWindow)
610 {
611 g_return_val_if_fail(XFDASHBOARD_IS_WINDOW_TRACKER_WINDOW(inWindow), NULL);
612
613 return(CLUTTER_ACTOR(g_object_new(XFDASHBOARD_TYPE_LIVE_WINDOW_SIMPLE,
614 "window", inWindow,
615 NULL)));
616 }
617
618 /* Get/set window to show */
xfdashboard_live_window_simple_get_window(XfdashboardLiveWindowSimple * self)619 XfdashboardWindowTrackerWindow* xfdashboard_live_window_simple_get_window(XfdashboardLiveWindowSimple *self)
620 {
621 g_return_val_if_fail(XFDASHBOARD_IS_LIVE_WINDOW_SIMPLE(self), NULL);
622
623 return(self->priv->window);
624 }
625
xfdashboard_live_window_simple_set_window(XfdashboardLiveWindowSimple * self,XfdashboardWindowTrackerWindow * inWindow)626 void xfdashboard_live_window_simple_set_window(XfdashboardLiveWindowSimple *self, XfdashboardWindowTrackerWindow *inWindow)
627 {
628 XfdashboardLiveWindowSimplePrivate *priv;
629
630 g_return_if_fail(XFDASHBOARD_IS_LIVE_WINDOW_SIMPLE(self));
631 g_return_if_fail(!inWindow || XFDASHBOARD_IS_WINDOW_TRACKER_WINDOW(inWindow));
632
633 priv=self->priv;
634
635 /* Only set value if it changes */
636 if(inWindow==priv->window) return;
637
638 /* Release old value */
639 if(priv->window)
640 {
641 g_signal_handlers_disconnect_by_data(priv->window, self);
642 priv->window=NULL;
643 }
644
645 /* Set new value
646 * Window tracker objects should never be refed or unrefed, so just set new value
647 */
648 priv->window=inWindow;
649 if(priv->window)
650 {
651 /* Get visibility state of window */
652 priv->isVisible=_xfdashboard_live_window_simple_is_visible_window(self, priv->window);
653
654 /* Setup window actor content */
655 _xfdashboard_live_window_simple_setup_content(self);
656
657 /* Set up this actor and child actor by calling each signal handler now */
658 _xfdashboard_live_window_simple_on_geometry_changed(self, priv->window);
659 _xfdashboard_live_window_simple_on_state_changed(self, 0, priv->window);
660 _xfdashboard_live_window_simple_on_workspace_changed(self, NULL, priv->window);
661
662 /* Connect signal handlers */
663 g_signal_connect_swapped(priv->window, "geometry-changed", G_CALLBACK(_xfdashboard_live_window_simple_on_geometry_changed), self);
664 g_signal_connect_swapped(priv->window, "state-changed", G_CALLBACK(_xfdashboard_live_window_simple_on_state_changed), self);
665 g_signal_connect_swapped(priv->window, "workspace-changed", G_CALLBACK(_xfdashboard_live_window_simple_on_workspace_changed), self);
666 g_signal_connect_swapped(priv->window, "closed", G_CALLBACK(_xfdashboard_live_window_simple_on_closed), self);
667 }
668 else
669 {
670 /* Clean window actor */
671 clutter_actor_set_content(priv->actorWindow, NULL);
672
673 /* Set window to invisible as NULL window is no window */
674 priv->isVisible=FALSE;
675 }
676
677 /* Notify about property change */
678 g_object_notify_by_pspec(G_OBJECT(self), XfdashboardLiveWindowSimpleProperties[PROP_WINDOW]);
679 }
680
681 /* Get/set display type of window */
xfdashboard_live_window_simple_get_display_type(XfdashboardLiveWindowSimple * self)682 XfdashboardLiveWindowSimpleDisplayType xfdashboard_live_window_simple_get_display_type(XfdashboardLiveWindowSimple *self)
683 {
684 g_return_val_if_fail(XFDASHBOARD_IS_LIVE_WINDOW_SIMPLE(self), XFDASHBOARD_LIVE_WINDOW_SIMPLE_DISPLAY_TYPE_LIVE_PREVIEW);
685
686 return(self->priv->displayType);
687 }
688
xfdashboard_live_window_simple_set_display_type(XfdashboardLiveWindowSimple * self,XfdashboardLiveWindowSimpleDisplayType inType)689 void xfdashboard_live_window_simple_set_display_type(XfdashboardLiveWindowSimple *self, XfdashboardLiveWindowSimpleDisplayType inType)
690 {
691 XfdashboardLiveWindowSimplePrivate *priv;
692
693 g_return_if_fail(XFDASHBOARD_IS_LIVE_WINDOW_SIMPLE(self));
694 g_return_if_fail(inType>=XFDASHBOARD_LIVE_WINDOW_SIMPLE_DISPLAY_TYPE_LIVE_PREVIEW && inType<=XFDASHBOARD_LIVE_WINDOW_SIMPLE_DISPLAY_TYPE_ICON);
695
696 priv=self->priv;
697
698 /* Only set value if it changes */
699 if(priv->displayType!=inType)
700 {
701 /* Set value */
702 priv->displayType=inType;
703
704 /* Setup window actor content */
705 _xfdashboard_live_window_simple_setup_content(self);
706
707 /* Notify about property change */
708 g_object_notify_by_pspec(G_OBJECT(self), XfdashboardLiveWindowSimpleProperties[PROP_DISPLAY_TYPE]);
709 }
710 }
711
712 /* Get/set flag for destruction on window close */
xfdashboard_live_window_simple_get_destroy_on_close(XfdashboardLiveWindowSimple * self)713 gboolean xfdashboard_live_window_simple_get_destroy_on_close(XfdashboardLiveWindowSimple *self)
714 {
715 g_return_val_if_fail(XFDASHBOARD_IS_LIVE_WINDOW_SIMPLE(self), FALSE);
716
717 return(self->priv->destroyOnClose);
718 }
719
xfdashboard_live_window_simple_set_destroy_on_close(XfdashboardLiveWindowSimple * self,gboolean inDestroyOnClose)720 void xfdashboard_live_window_simple_set_destroy_on_close(XfdashboardLiveWindowSimple *self, gboolean inDestroyOnClose)
721 {
722 XfdashboardLiveWindowSimplePrivate *priv;
723
724 g_return_if_fail(XFDASHBOARD_IS_LIVE_WINDOW_SIMPLE(self));
725
726 priv=self->priv;
727
728 /* Only set value if it changes */
729 if(priv->destroyOnClose!=inDestroyOnClose)
730 {
731 /* Set value */
732 priv->destroyOnClose=inDestroyOnClose;
733
734 /* Notify about property change */
735 g_object_notify_by_pspec(G_OBJECT(self), XfdashboardLiveWindowSimpleProperties[PROP_DESTROY_ON_CLOSE]);
736 }
737 }
738