[Xfce4-commits] <xfce4-wmdock-plugin:master> Working on the implementation of panel off dockapp movement.
Andre Ellguth
noreply at xfce.org
Mon Nov 4 13:36:07 CET 2013
Updating branch refs/heads/master
to 59a627add3b45886ba8d76b8fb40a2f1cbed6e6c (commit)
from dfca92e3613b7d672ca8d6c6b18ebee73103c83e (commit)
commit 59a627add3b45886ba8d76b8fb40a2f1cbed6e6c
Author: Andre Ellguth <andre at ellguth.com>
Date: Thu Jul 18 22:30:39 2013 +0200
Working on the implementation of panel off dockapp movement.
panel-plugin/catchwindow.c | 2 +-
panel-plugin/dockapp.c | 238 ++++++++++++++++++++++++++++----------------
panel-plugin/dockapp.h | 4 +-
3 files changed, 155 insertions(+), 89 deletions(-)
diff --git a/panel-plugin/catchwindow.c b/panel-plugin/catchwindow.c
index 2f73557..c630993 100644
--- a/panel-plugin/catchwindow.c
+++ b/panel-plugin/catchwindow.c
@@ -122,7 +122,7 @@ void wmdock_window_open(WnckScreen *s, WnckWindow *w)
|| has_dockapp_hint(w)) {
debug("catchwindow.c: new wmapp open");
- debug("catchwindow.c: New dockapp %s with xid:%u pid:%u arrived sessid:%s",
+ debug("catchwindow.c: New dockapp %s with xid: 0x%x pid: %u arrived sessid: %s",
wnck_window_get_name(w), wnck_window_get_xid(w),
wnck_window_get_pid(w), wnck_window_get_session_id(w));
diff --git a/panel-plugin/dockapp.c b/panel-plugin/dockapp.c
index 8f32ea5..302df65 100644
--- a/panel-plugin/dockapp.c
+++ b/panel-plugin/dockapp.c
@@ -49,8 +49,6 @@ static GtkTargetEntry targetList[] = {
{ "INTEGER", 0, 0 }
};
static guint nTargets = G_N_ELEMENTS (targetList);
-static DockappNode *dummy = NULL;
-
/**
* Get the x coordinate child dockapp.
@@ -70,8 +68,7 @@ static void wmdock_dockapp_child_pos(DockappNode *prevDapp, gint gluepos, gint *
/* Get the position of the previous DockApp if is accessable. */
gtk_window_get_position(
- GTK_WINDOW (GTK_WIDGET (prevDapp->tile)),
- &prevx, &prevy);
+ GTK_WINDOW (GTK_WIDGET (prevDapp->tile)), &prevx, &prevy);
switch(gluepos) {
case GLUE_T:
@@ -111,53 +108,103 @@ static void wmdock_dockapp_child_pos(DockappNode *prevDapp, gint gluepos, gint *
}
}
-
/**
- * Insert a dummy and move dockapp and replace the other dockapps.
+ * Calculate the next snapable postion of the moving DockApp.
*
- * @param dapp Position for dummy placement.
+ * @parm dapp The moving DockApp.
+ * @parm gluepos Pointer to the glue position of the determined DockApp.
+ * @return The determined DockApp or NULL.
*/
-static void wmdock_insert_dummy(DockappNode *dapp)
+static DockappNode *wmdock_determine_snapable_dockapp(DockappNode *dapp, gint *gluepos)
{
- gint i, x, y;
+ #define SNAPDELTA (DEFAULT_DOCKAPP_HEIGHT/2)-1
+ gint posx, posy, gluex, gluey;
+ GList *dapps;
+ DockappNode *_dapp = NULL;
- if(!dummy) {
- dummy = g_new0(DockappNode, 1);
- dummy->name = g_strdup(DOCKAPP_DUMMY_TITLE);
- dummy->tile = wmdock_create_dummy();
- }
+ gtk_window_get_position(
+ GTK_WINDOW (GTK_WIDGET (dapp->tile)), &posx, &posy);
- for(i = 0; i < GLUE_MAX; i++)
- dummy->glue[i] = dapp->glue[i];
+ dapps = g_list_first(wmdock->dapps);
- gtk_widget_show(dummy->tile);
+ while(dapps) {
+ if((_dapp = DOCKAPP(dapps->data))) {
+ for(*gluepos = 0; *gluepos < GLUE_MAX; *gluepos=*gluepos+1) {
+ if(!_dapp->glue[*gluepos] || !g_strcmp0(_dapp->glue[*gluepos]->name, DOCKAPP_DUMMY_TITLE)) {
+ wmdock_dockapp_child_pos(_dapp, *gluepos, &gluex, &gluey);
+ if(posx >= gluex-SNAPDELTA && posy >= gluey-SNAPDELTA &&
+ posx <= gluex+SNAPDELTA && posy <= gluey+SNAPDELTA)
+ return _dapp;
+ }
+ }
+ }
- gtk_window_get_position(GTK_WINDOW(dapp->tile), &x, &y);
- debug("dockapp.c: Move dummy dockapp to x: %d, y: %d", x, y);
- gtk_window_move(GTK_WINDOW(dummy->tile), x, y);
+ dapps = g_list_next(dapps);
+ }
- wmdock_order_dockapps(dummy);
+ return NULL;
}
-static void wmdock_destroy_dummy()
+/**
+ * Remove anchors of dummy DockApp.
+ */
+static void wmdock_remove_anchors_tile_dummy()
{
- if(!dummy)
- return;
+ gint i;
+ GList *dapps;
+ DockappNode *_dapp = NULL;
- /* Kick all dummy dockapps in list. */
- if(g_list_find(wmdock->dapps, dummy))
- wmdock->dapps = g_list_remove(wmdock->dapps, dummy);
+ dapps = g_list_first(wmdock->dapps);
+ while(dapps) {
+ if((_dapp = DOCKAPP(dapps->data))) {
+ for(i = 0; i < GLUE_MAX; i++) {
+ if(_dapp->glue[i] && !g_strcmp0(_dapp->glue[i]->name, DOCKAPP_DUMMY_TITLE)) {
+ _dapp->glue[i] = NULL;
+ }
+ }
+ }
- gtk_widget_destroy(dummy->tile);
- g_free(dummy->name);
- g_free(dummy);
+ dapps = g_list_next(dapps);
+ }
+}
- dummy = NULL;
- wmdock_order_dockapps(DOCKAPP(g_list_first(wmdock->dapps)->data));
-}
+/**
+ * Replace dummy DockApp with the moved DockApp.
+ *
+ * @param dapp Replacement Dockapp.
+ * @return TRUE if dummy tile is replaced else FALSE.
+ */
+static gboolean wmdock_replace_tile_dummy(DockappNode *dapp)
+{
+ gint i;
+ GList *dapps;
+ DockappNode *_dapp = NULL;
+ dapps = g_list_first(wmdock->dapps);
+ while(dapps) {
+ if((_dapp = DOCKAPP(dapps->data))) {
+ for(i = 0; i < GLUE_MAX; i++) {
+ if(_dapp->glue[i] && !g_strcmp0(_dapp->glue[i]->name, DOCKAPP_DUMMY_TITLE)) {
+ g_list_foreach(wmdock->dapps, (GFunc) wmdock_remove_anchor_dockapp, dapp);
+ _dapp->glue[i] = dapp;
+ for(i = 0; i < GLUE_MAX; i++) {
+ if(dapp->glue[i] == _dapp) {
+ /* Remove old anchor itself. */
+ dapp->glue[i] = NULL;
+ }
+ }
+ return TRUE;
+ }
+ }
+ }
+
+ dapps = g_list_next(dapps);
+ }
+
+ return FALSE;
+}
/**
* Event handler for the tile in panel off mode.
@@ -168,49 +215,66 @@ static void wmdock_destroy_dummy()
*/
void wmdock_dockapp_paneloff_handler(GtkWidget *tile, GdkEvent *ev, DockappNode *dapp)
{
- static DockappNode *dappOnMove = NULL;
+ static DockappNode *dappOnMove = NULL, *dappDummy = NULL;
+ DockappNode *dappSnap = NULL;
+ gint gluepos;
debug("dockapp.c: Window event: %d. (dapp: %s), dappOnMove: %s", ev->type, dapp->name,
dappOnMove ? "Yes": "No");
switch(ev->type) {
case GDK_CONFIGURE: /* Movement. */
- if(dappOnMove)
- break;
+ if(dappOnMove) {
+ wmdock_remove_anchors_tile_dummy();
+ dappSnap = wmdock_determine_snapable_dockapp(dapp, &gluepos);
+ if(dappSnap) {
+ debug("dockapp.c: Snapable dockapp `%s' for dockapp `%s', glue: %d.", dappSnap->name, dapp->name, gluepos);
+ if(!dappDummy) {
+ dappDummy = g_new0(DockappNode, 1);
+ dappDummy->name = g_strdup(DOCKAPP_DUMMY_TITLE);
+ dappDummy->tile = wmdock_create_tile_dummy();
+ }
+
+ dappSnap->glue[gluepos] = dappDummy;
+ wmdock_order_dockapps(dappDummy);
+ gtk_widget_show_all(dappDummy->tile);
+ } else if(dappDummy) {
+ gtk_widget_hide(dappDummy->tile);
+ }
+ }
break;
case GDK_BUTTON_PRESS:
case GDK_KEY_PRESS:
dappOnMove = dapp;
-
break;
case GDK_BUTTON_RELEASE:
case GDK_KEY_RELEASE:
- debug("dockapp.c: Window event button release on %s.", dapp->name);
- wmdock_set_autoposition_dockapp(dapp, wmdock_get_parent_dockapp(dapp));
+ debug("dockapp.c: Window event button release on `%s'.", dapp->name);
+ if(wmdock_replace_tile_dummy(dapp) == TRUE) {
+ debug("dockapp.c: Replaceable dummy tile found.");
+ wmdock_order_dockapps(DOCKAPP(g_list_first(wmdock->dapps)->data));
+ } else {
+ wmdock_remove_anchors_tile_dummy();
+ wmdock_set_autoposition_dockapp(dapp, wmdock_get_parent_dockapp(dapp));
+ }
+ if(dappDummy) {
+ gtk_widget_hide(dappDummy->tile);
+ }
dappOnMove = NULL;
- wmdock_destroy_dummy();
+
break;
case GDK_FOCUS_CHANGE:
if(ev->focus_change.in == TRUE) {
/* `in' is true if window window got the focus. */
g_list_foreach(wmdock->dapps, (GFunc) wmdock_dockapp_tofront, NULL);
}
-
- break;
- case GDK_VISIBILITY_NOTIFY:
if(dappOnMove) {
- if(dapp == dappOnMove)
- break;
-
- if(ev->visibility.state == GDK_VISIBILITY_PARTIAL ||
- ev->visibility.state == GDK_VISIBILITY_FULLY_OBSCURED) {
- // wmdock_insert_dummy(dapp);
- }
- } else {
- wmdock_redraw_dockapp(dapp);
- wmdock_destroy_dummy();
+ wmdock_set_autoposition_dockapp(dapp, wmdock_get_parent_dockapp(dapp));
}
break;
+ case GDK_VISIBILITY_NOTIFY:
+ wmdock_redraw_dockapp(dapp);
+ break;
default:
break;
}
@@ -218,6 +282,40 @@ void wmdock_dockapp_paneloff_handler(GtkWidget *tile, GdkEvent *ev, DockappNode
/**
+ * Creates a dummy tile without any dockapp in it.
+ *
+ * @return A GTK window widget.
+ */
+GtkWidget *wmdock_create_tile_dummy()
+{
+ GtkWidget *dummy = NULL;
+
+ dummy = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+
+ gtk_window_set_default_size(GTK_WINDOW(dummy), DEFAULT_DOCKAPP_WIDTH,
+ DEFAULT_DOCKAPP_HEIGHT);
+ gtk_container_set_border_width(GTK_CONTAINER(dummy), 0);
+
+ /* Disable window shrinking resizing and growing. */
+ gtk_window_set_policy (GTK_WINDOW(dummy), FALSE, FALSE, FALSE);
+ gtk_window_set_decorated(GTK_WINDOW(dummy), FALSE);
+ gtk_window_set_resizable(GTK_WINDOW(dummy), FALSE);
+ /* Window visible on all workspaces. */
+ gtk_window_stick(GTK_WINDOW(dummy));
+ gtk_window_set_focus_on_map(GTK_WINDOW(dummy), FALSE);
+ /* Hide window from the taskbar and the pager. */
+ gtk_window_set_skip_taskbar_hint(GTK_WINDOW(dummy), TRUE);
+ gtk_window_set_skip_pager_hint(GTK_WINDOW(dummy), TRUE);
+ gtk_window_set_opacity(GTK_WINDOW(dummy), 0.6);
+ gtk_widget_set_size_request(dummy, DEFAULT_DOCKAPP_WIDTH, DEFAULT_DOCKAPP_HEIGHT);
+ gtk_window_set_keep_below(GTK_WINDOW(dummy), TRUE);
+ gtk_window_set_type_hint(GTK_WINDOW(dummy), GDK_WINDOW_TYPE_HINT_DND);
+
+ return (dummy);
+}
+
+
+/**
* Set focus to a dockapp.
*
* @param dapp DockappNode to focus.
@@ -288,7 +386,7 @@ DockappNode *wmdock_find_startup_dockapp(const gchar *compCmd)
GList *dapps;
DockappNode *dapp = NULL;
- dapps = wmdock->dapps;
+ dapps = g_list_first(wmdock->dapps);
while(dapps) {
dapp = DOCKAPP(dapps->data);
@@ -516,38 +614,6 @@ void wmdock_set_tile_background(DockappNode *dapp, GdkPixbuf *pb)
}
-/**
- * Creates a dummy tile without any dockapp in it.
- *
- * @return A GTK window widget.
- */
-GtkWidget *wmdock_create_dummy()
-{
- GtkWidget *dummy = NULL;
-
- dummy = gtk_window_new(GTK_WINDOW_TOPLEVEL);
-
- gtk_window_set_default_size(GTK_WINDOW(dummy), DEFAULT_DOCKAPP_WIDTH,
- DEFAULT_DOCKAPP_HEIGHT);
- gtk_container_set_border_width(GTK_CONTAINER(dummy), 0);
-
- /* Disable window shrinking resizing and growing. */
- gtk_window_set_policy (GTK_WINDOW(dummy), FALSE, FALSE, FALSE);
- gtk_window_set_decorated(GTK_WINDOW(dummy), FALSE);
- gtk_window_set_resizable(GTK_WINDOW(dummy), FALSE);
- /* Window visible on all workspaces. */
- gtk_window_stick(GTK_WINDOW(dummy));
- gtk_window_set_focus_on_map(GTK_WINDOW(dummy), FALSE);
- /* Hide window from the taskbar and the pager. */
- gtk_window_set_skip_taskbar_hint(GTK_WINDOW(dummy), TRUE);
- gtk_window_set_skip_pager_hint(GTK_WINDOW(dummy), TRUE);
- gtk_window_set_opacity(GTK_WINDOW(dummy), 0.6);
- gtk_widget_set_size_request(dummy, DEFAULT_DOCKAPP_WIDTH, DEFAULT_DOCKAPP_HEIGHT);
-
- return (dummy);
-}
-
-
GtkWidget *wmdock_create_tile_from_socket(DockappNode *dapp)
{
GtkWidget *align = NULL;
diff --git a/panel-plugin/dockapp.h b/panel-plugin/dockapp.h
index a793e09..035f5b9 100644
--- a/panel-plugin/dockapp.h
+++ b/panel-plugin/dockapp.h
@@ -49,7 +49,7 @@ struct _dockapp {
DockappNode *glue[GLUE_MAX];
};
-#define DOCKAPP_DUMMY_TITLE "_dummy_"
+#define DOCKAPP_DUMMY_TITLE "__WMDOCK_dummy__"
#define DOCKAPP(__dapp) ((DockappNode *) __dapp)
gboolean wmdock_startup_dockapp(const gchar *);
@@ -70,6 +70,6 @@ void wmdock_dockapp_tofront(DockappNode *dapp);
void wmdock_dockapp_paneloff_handler(GtkWidget *, GdkEvent *, DockappNode *);
void wmdock_remove_anchor_dockapp(DockappNode *, DockappNode *);
void wmdock_order_dockapps(DockappNode *);
-GtkWidget *wmdock_create_dummy();
+GtkWidget *wmdock_create_tile_dummy();
#endif /* __DOCKAPP_H__ */
More information about the Xfce4-commits
mailing list